@wildo-ai/saas-technical-doc 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/build/csp-emit.d.ts.map +1 -1
- package/dist/esm/build/load-materialized-frontend-providers.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-administration-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-administration-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts +37 -0
- package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.js +46 -5
- package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts +101 -0
- package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts.map +1 -0
- package/dist/esm/companion/application-documentation/application-documentation-chapters.js +205 -0
- package/dist/esm/companion/application-documentation/application-documentation-chapters.js.map +1 -0
- package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-domain-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-integration-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-role-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.js +3 -0
- package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts +34 -0
- package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts.map +1 -0
- package/dist/esm/companion/application-documentation/docs-api-origin-substitution.js +45 -0
- package/dist/esm/companion/application-documentation/docs-api-origin-substitution.js.map +1 -0
- package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts +24 -10
- package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js +25 -15
- package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-operational-evidence.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts +11 -3
- package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js +9 -2
- package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js +10 -4
- package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js.map +1 -1
- package/dist/esm/companion/content/application-consumer-documentation-content-loader.d.ts.map +1 -1
- package/dist/esm/companion/index.d.ts +2 -0
- package/dist/esm/companion/index.d.ts.map +1 -1
- package/dist/esm/companion/index.js +2 -0
- package/dist/esm/companion/index.js.map +1 -1
- package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -1
- package/dist/esm/companion/manual-controller-route-projection.js.map +1 -1
- package/dist/esm/companion/openapi-example-derivation.d.ts +53 -0
- package/dist/esm/companion/openapi-example-derivation.d.ts.map +1 -0
- package/dist/esm/companion/openapi-example-derivation.js +229 -0
- package/dist/esm/companion/openapi-example-derivation.js.map +1 -0
- package/dist/esm/companion/openapi-generator.d.ts +8 -4
- package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
- package/dist/esm/companion/openapi-generator.js +323 -33
- package/dist/esm/companion/openapi-generator.js.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.d.ts +57 -1
- package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.js +29 -0
- package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
- package/dist/esm/companion/publish-result.types.d.ts.map +1 -1
- package/dist/esm/companion/publish-result.types.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-authorized-bundle-reader.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js +8 -0
- package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js +20 -0
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts +2 -0
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js +48 -31
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-render-model.js +26 -10
- package/dist/esm/companion/rendering/technical-documentation-render-model.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.js.map +1 -1
- package/dist/esm/companion/spec-to-operation-doc.d.ts +52 -10
- package/dist/esm/companion/spec-to-operation-doc.d.ts.map +1 -1
- package/dist/esm/companion/spec-to-operation-doc.js +125 -7
- package/dist/esm/companion/spec-to-operation-doc.js.map +1 -1
- package/dist/esm/companion/technical-documentation-asset-path.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-capture-execution-port.js.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-definitions.js.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-materializer.js.map +1 -1
- package/dist/esm/companion/technical-documentation-placeholder-materializer.d.ts.map +1 -1
- package/dist/esm/companion/zod-to-openapi.d.ts.map +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/config/define-tech-doc-config.d.ts.map +1 -1
- package/dist/esm/config/index.d.ts.map +1 -1
- package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
- package/dist/esm/config/wildo-tech-doc-config.schemas.js.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content-manifest.schemas.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +27 -24
- package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content.techdoc.js +205 -82
- package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
- package/dist/esm/content.exports.d.ts.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-link-index.d.ts +3 -0
- package/dist/esm/openapi/api-reference-link-index.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-link-index.js +26 -15
- package/dist/esm/openapi/api-reference-link-index.js.map +1 -1
- package/dist/esm/openapi/api-reference-pages.d.ts +55 -0
- package/dist/esm/openapi/api-reference-pages.d.ts.map +1 -0
- package/dist/esm/openapi/api-reference-pages.js +229 -0
- package/dist/esm/openapi/api-reference-pages.js.map +1 -0
- package/dist/esm/openapi/api-reference-search.d.ts +53 -0
- package/dist/esm/openapi/api-reference-search.d.ts.map +1 -0
- package/dist/esm/openapi/api-reference-search.js +100 -0
- package/dist/esm/openapi/api-reference-search.js.map +1 -0
- package/dist/esm/openapi/api-reference-targets.d.ts +11 -0
- package/dist/esm/openapi/api-reference-targets.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-targets.js +8 -0
- package/dist/esm/openapi/api-reference-targets.js.map +1 -1
- package/dist/esm/openapi/index.d.ts +2 -0
- package/dist/esm/openapi/index.d.ts.map +1 -1
- package/dist/esm/openapi/index.js +2 -0
- package/dist/esm/openapi/index.js.map +1 -1
- package/dist/esm/openapi/openapi-generation-output.schemas.d.ts.map +1 -1
- package/dist/esm/openapi-reference-model.exports.d.ts +2 -0
- package/dist/esm/openapi-reference-model.exports.d.ts.map +1 -1
- package/dist/esm/openapi-reference-model.exports.js +2 -0
- package/dist/esm/openapi-reference-model.exports.js.map +1 -1
- package/dist/esm/runtime/AuthExchangePage.d.ts +45 -4
- package/dist/esm/runtime/AuthExchangePage.d.ts.map +1 -1
- package/dist/esm/runtime/AuthExchangePage.js +45 -12
- package/dist/esm/runtime/AuthExchangePage.js.map +1 -1
- package/dist/esm/runtime/DocsAuthContext.d.ts +2 -2
- package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
- package/dist/esm/runtime/DocsAuthContext.js +8 -4
- package/dist/esm/runtime/DocsAuthContext.js.map +1 -1
- package/dist/esm/runtime/DocsFrontendProviders.d.ts +30 -0
- package/dist/esm/runtime/DocsFrontendProviders.d.ts.map +1 -0
- package/dist/esm/runtime/DocsFrontendProviders.js +39 -0
- package/dist/esm/runtime/DocsFrontendProviders.js.map +1 -0
- package/dist/esm/runtime/DocsProviderComponent.d.ts +41 -0
- package/dist/esm/runtime/DocsProviderComponent.d.ts.map +1 -0
- package/dist/esm/runtime/DocsProviderComponent.js +17 -0
- package/dist/esm/runtime/DocsProviderComponent.js.map +1 -0
- package/dist/esm/runtime/decode-jwt-claims.d.ts.map +1 -1
- package/dist/esm/runtime/docs-auth-client.d.ts.map +1 -1
- package/dist/esm/runtime/docs-auth-session.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/documentation-site-translator.d.ts +53 -0
- package/dist/esm/runtime/documentation-site-translator.d.ts.map +1 -0
- package/dist/esm/runtime/documentation-site-translator.js +51 -0
- package/dist/esm/runtime/documentation-site-translator.js.map +1 -0
- package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts +1 -2
- package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
- package/dist/esm/runtime/frontend-provider-registry.techdoc.js.map +1 -1
- package/dist/esm/runtime/index.d.ts +8 -0
- package/dist/esm/runtime/index.d.ts.map +1 -1
- package/dist/esm/runtime/index.js +8 -0
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-conservation.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-model.d.ts +30 -0
- package/dist/esm/runtime/openapi-reference-model.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-model.js +85 -11
- package/dist/esm/runtime/openapi-reference-model.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-navigation.d.ts +50 -0
- package/dist/esm/runtime/openapi-reference-navigation.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-navigation.js +46 -0
- package/dist/esm/runtime/openapi-reference-navigation.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-samples.d.ts +40 -0
- package/dist/esm/runtime/openapi-reference-samples.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-samples.js +169 -0
- package/dist/esm/runtime/openapi-reference-samples.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-styles.d.ts +28 -0
- package/dist/esm/runtime/openapi-reference-styles.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-styles.js +292 -0
- package/dist/esm/runtime/openapi-reference-styles.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-view.d.ts +40 -5
- package/dist/esm/runtime/openapi-reference-view.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-view.js +828 -82
- package/dist/esm/runtime/openapi-reference-view.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-words-context.d.ts +12 -0
- package/dist/esm/runtime/openapi-reference-words-context.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-words-context.js +30 -0
- package/dist/esm/runtime/openapi-reference-words-context.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-words.d.ts +205 -0
- package/dist/esm/runtime/openapi-reference-words.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-words.js +162 -0
- package/dist/esm/runtime/openapi-reference-words.js.map +1 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.d.ts +31 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.d.ts.map +1 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.js +35 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.js.map +1 -0
- package/dist/esm/runtime/use-docs-auth-session.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts +1 -0
- package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-frontend-provider-registry.js +10 -2
- package/dist/esm/runtime/use-docs-frontend-provider-registry.js.map +1 -1
- package/dist/esm/runtime/use-docs-provider-component.d.ts +29 -0
- package/dist/esm/runtime/use-docs-provider-component.d.ts.map +1 -0
- package/dist/esm/runtime/use-docs-provider-component.js +42 -0
- package/dist/esm/runtime/use-docs-provider-component.js.map +1 -0
- package/dist/esm/runtime/use-docs-provider-scripts.d.ts +37 -0
- package/dist/esm/runtime/use-docs-provider-scripts.d.ts.map +1 -0
- package/dist/esm/runtime/use-docs-provider-scripts.js +47 -0
- package/dist/esm/runtime/use-docs-provider-scripts.js.map +1 -0
- package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-provider-sdks.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +8 -24
package/dist/esm/companion/application-documentation/application-documentation-chapters.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-documentation-chapters.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-documentation-chapters.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The chapters an APPLICATION authors, joined to the plan that declares them and projected into\n * publishable units (#874).\n *\n * Until this module the portal could say only what the engine wrote or what the companion projected:\n * a customer could read a page per resource, and nothing about the journeys that cross them, and\n * the private derivation's own contract said application content stayed absent until the\n * app-creator owned an accepted authoring artifact. Two accepted artifacts now exist, both\n * specification FILES accepted by being committed:\n *\n * | artifact | owns |\n * | --- | --- |\n * | the documentation plan (`documentationPlan`) | each chapter's identity — ref, title, kind, audiences |\n * | the authored chapters (`documentationChapters`) | each chapter's body, classification, API references |\n *\n * This is the join, and it mirrors the framework's own catalogue: authored Markdown joined to a unit\n * definition by key, with the projector refusing a content set that does not match its definitions.\n *\n * ## What is refused, and what is merely withheld\n *\n * | condition | outcome | why |\n * | --- | --- | --- |\n * | a chapter no plan declares (or no plan at all) | withheld, and reported (`authoredChapterRefsWithoutPlan`) | the plan owns the chapter's title, kind and audiences, so there is nothing true to publish it under — but the body is unfinished work, not a false statement |\n * | a `RESTRICTED` chapter | withheld by the publication policy (`RESTRICTED_SOURCE`) | the chapter is true, and not for this audience |\n * | a `DRAFT` / `REVIEW_REQUIRED` chapter | withheld by the policy (`EDITORIAL_NOT_APPROVED`) | the author said it is not ready |\n * | a planned chapter with no body yet | not published, and reported | unfinished rather than false |\n * | an API reference the rendered reference does not carry | THROWS at publication | see {@link assertApplicationDocumentationChapterApiReferencesResolve} |\n *\n * Refusal is kept to the one case where publishing would state something untrue — a guide telling a\n * reader to call an operation that does not exist. Everything else is withheld and reported, so it\n * travels with the artifact and stops nothing (`application-creation-directive.md`).\n *\n * Rejected alternative, kept here because it was the first version: REFUSING an unplanned body. It\n * made one orphaned chapter — a plan ref renamed, a draft written ahead of its plan entry — stop the\n * whole portal, including the build lane's derived publication step, although withholding that body\n * publishes nothing untrue.\n */\nimport {\n ApplicationDocumentationPlanDisposition,\n TechnicalDocumentationAccessClass,\n TechnicalDocumentationApiReferenceSection,\n TechnicalDocumentationApiReferenceTargetKind,\n TechnicalDocumentationEditorialStatus,\n TechnicalDocumentationLinkKind,\n TechnicalDocumentationSourceOwnership,\n DOCUMENTATION_CHAPTER_REF_PREFIX,\n ApplicationDocumentationChapterSetSchema,\n ApplicationDocumentationPlanSchema,\n createTechnicalDocumentationUnitV1,\n type ApplicationDocumentationChapterApiReference,\n type ApplicationDocumentationChapterSet,\n type ApplicationDocumentationPlan,\n type TechnicalDocumentationApiReferenceTargetV1,\n type TechnicalDocumentationAuthorizedBundleManifestV1,\n type TechnicalDocumentationLinkV1,\n type TechnicalDocumentationUnitV1,\n} from '@wildo-ai/saas-specifications/technical-documentation';\n\nimport {\n getTechnicalDocumentationApiReferenceTargetAvailability,\n TechnicalDocumentationApiReferenceTargetAvailability,\n type ApiReferenceLinkIndex,\n} from '../../openapi/api-reference-link-index';\nimport { parseTechnicalDocumentationUnitMarkdown } from './technical-documentation-engine-content-bundle';\n\n/**\n * The unit-ref namespace authored chapters live in, and the only place its shape is written.\n *\n * A RESERVED engine namespace, like `unit/manages/`: the renderer routes it to `guides/<slug>`, so\n * an application chooses a chapter's slug but never its URL scheme, and nothing an application names\n * can land in the engine's own route table.\n */\nexport const APPLICATION_DOCUMENTATION_CHAPTER_UNIT_REF_PREFIX = 'technical-documentation:unit/guides/';\n\n/** The portal directory every authored chapter is published under. */\nexport const APPLICATION_DOCUMENTATION_CHAPTER_ROUTE_DIRECTORY = 'guides';\n\n/** Provenance ref of one authored chapter — the file a reader traces the page back to. */\nexport const APPLICATION_DOCUMENTATION_CHAPTER_SOURCE_PREFIX = 'source:application-chapter:';\n\n/**\n * The only version an authored chapter carries. A chapter is versioned by git, not by a counter in\n * the file (`one-source-of-truth.md`); the unit schema requires a positive version, and 1 states\n * that nothing else is being claimed.\n */\nconst APPLICATION_DOCUMENTATION_CHAPTER_SOURCE_VERSION = 1;\n\n/** `chapter-close-a-deal` → `close-a-deal`: the slug a route and a unit ref are built from. */\nexport function applicationDocumentationChapterSlug(chapterRef: string): string {\n if (!chapterRef.startsWith(DOCUMENTATION_CHAPTER_REF_PREFIX)) {\n throw new Error(`documentation chapter ref ${chapterRef} does not start with ${DOCUMENTATION_CHAPTER_REF_PREFIX}`);\n }\n return chapterRef.slice(DOCUMENTATION_CHAPTER_REF_PREFIX.length);\n}\n\nexport function applicationDocumentationChapterUnitRef(chapterRef: string): string {\n return `${APPLICATION_DOCUMENTATION_CHAPTER_UNIT_REF_PREFIX}${applicationDocumentationChapterSlug(chapterRef)}`;\n}\n\n/**\n * The portable target one authored API reference names.\n *\n * Built with `encodeURIComponent`, exactly as the OpenAPI identity constructor builds the refs it\n * indexes (`createOpenApiOperationIdentity`) — so an operation named `complete-all` or one carrying a\n * `:` resolves to the same key on both sides rather than failing on an encoding difference.\n */\nexport function applicationDocumentationChapterApiReferenceTarget(reference: ApplicationDocumentationChapterApiReference): TechnicalDocumentationApiReferenceTargetV1 {\n const resourceRef = `technical-documentation:resource/${encodeURIComponent(reference.resource)}`;\n // Omitted means the public API reference, which is where almost every contract a guide cites lives.\n const section = reference.section ?? TechnicalDocumentationApiReferenceSection.API_REFERENCE;\n return reference.operation === undefined\n ? {\n section,\n kind: TechnicalDocumentationApiReferenceTargetKind.RESOURCE,\n resourceRef,\n }\n : {\n section,\n kind: TechnicalDocumentationApiReferenceTargetKind.OPERATION_FAMILY,\n operationFamilyRef: `${resourceRef}/operation-family/${encodeURIComponent(reference.operation)}`,\n };\n}\n\nexport interface ProjectApplicationDocumentationChaptersInput {\n /** The accepted plan, as the specifications package exports it. Parsed here: the export is untyped at runtime. */\n readonly plan: unknown;\n /** The accepted chapter bodies, as the specifications package exports them. Parsed here too. */\n readonly chapters: unknown;\n}\n\nexport interface ApplicationDocumentationChaptersProjection {\n /** One unit per authored chapter, unfiltered: the publication policy decides what a reader sees. */\n readonly units: readonly TechnicalDocumentationUnitV1[];\n /** Chapters the plan declares whose body nobody has authored yet — reported, never refused. */\n readonly plannedChapterRefsWithoutBody: readonly string[];\n /**\n * Bodies authored under a `chapterRef` the accepted plan does not declare (or with no plan, or a\n * NOT_APPLICABLE one). Withheld — they have no title, kind or audience to publish under — and\n * reported, never refused.\n */\n readonly authoredChapterRefsWithoutPlan: readonly string[];\n}\n\n/**\n * Joins the authored chapters to the plan that declares them. A pure function of its two inputs.\n * A body the plan does not declare is withheld and reported — see the module table.\n */\nexport function projectApplicationDocumentationChapters(input: ProjectApplicationDocumentationChaptersInput): ApplicationDocumentationChaptersProjection {\n const chapters: ApplicationDocumentationChapterSet = input.chapters === undefined\n ? {}\n : ApplicationDocumentationChapterSetSchema.parse(input.chapters);\n const plan: ApplicationDocumentationPlan | undefined = input.plan === undefined\n ? undefined\n : ApplicationDocumentationPlanSchema.parse(input.plan);\n const plannedChapters = plan === undefined || plan.disposition === ApplicationDocumentationPlanDisposition.NOT_APPLICABLE ? [] : plan.chapters;\n const plannedByRef = new Map(plannedChapters.map((chapter) => [chapter.chapterRef, chapter]));\n\n const authoredChapterRefsWithoutPlan = Object.keys(chapters).filter((chapterRef) => !plannedByRef.has(chapterRef)).sort();\n\n const units = Object.entries(chapters)\n .filter(([chapterRef]) => plannedByRef.has(chapterRef))\n .sort(([left], [right]) => left.localeCompare(right, 'en-US'))\n .map(([chapterRef, chapter]) => {\n const planned = plannedByRef.get(chapterRef)!;\n const unitRef = applicationDocumentationChapterUnitRef(chapterRef);\n const slug = applicationDocumentationChapterSlug(chapterRef);\n const parsed = parseTechnicalDocumentationUnitMarkdown(`# ${planned.title}\\n\\n${chapter.body}`, unitRef);\n // A related chapter the plan does not declare is withheld above, so there is no page to link to.\n const relatedLinks: TechnicalDocumentationLinkV1[] = chapter.relatedChapterRefs\n .filter((relatedChapterRef) => plannedByRef.has(relatedChapterRef))\n .map((relatedChapterRef) => ({\n linkRef: `technical-documentation:link/guides-${slug}-to-${applicationDocumentationChapterSlug(relatedChapterRef)}`,\n kind: TechnicalDocumentationLinkKind.UNIT,\n // Filtered to planned chapters just above, so the title is always present.\n label: plannedByRef.get(relatedChapterRef)!.title,\n targetUnitRef: applicationDocumentationChapterUnitRef(relatedChapterRef),\n targetRef: null,\n externalUrl: null,\n apiReferenceTarget: null,\n }));\n const apiReferenceLinks: TechnicalDocumentationLinkV1[] = chapter.apiReferences.map((reference, index) => ({\n linkRef: `technical-documentation:link/guides-${slug}-api-reference-${String(index + 1).padStart(2, '0')}`,\n kind: TechnicalDocumentationLinkKind.API_REFERENCE,\n label: reference.label,\n targetUnitRef: null,\n targetRef: null,\n externalUrl: null,\n apiReferenceTarget: applicationDocumentationChapterApiReferenceTarget(reference),\n }));\n return createTechnicalDocumentationUnitV1({\n schemaVersion: 1,\n unitRef,\n unitVersion: 1,\n kind: planned.kind,\n readerAudiences: [...planned.readerAudiences],\n title: parsed.title,\n summary: parsed.summary,\n sections: parsed.sections.map((section, index) => ({\n sectionRef: `technical-documentation:section/guides-${slug}-${index + 1}`,\n heading: section.heading,\n bodyMarkdown: section.bodyMarkdown,\n })),\n links: [...relatedLinks, ...apiReferenceLinks],\n /*\n * ONE provenance row, carrying the author's own classification. That row is what the\n * publication policy reads: a `RESTRICTED` chapter is suppressed with `RESTRICTED_SOURCE`\n * by the same rule that suppresses any unit derived from a restricted source, so there is\n * no second, chapter-specific gate to drift from the first.\n */\n provenance: [{\n sourceRef: `${APPLICATION_DOCUMENTATION_CHAPTER_SOURCE_PREFIX}${chapterRef}`,\n ownership: TechnicalDocumentationSourceOwnership.APPLICATION_AUTHORED,\n classification: chapter.classification,\n sourceVersion: APPLICATION_DOCUMENTATION_CHAPTER_SOURCE_VERSION,\n sourceAnchorRef: null,\n }],\n applicabilityRequirements: [...chapter.applicabilityRequirements],\n accessClass: TechnicalDocumentationAccessClass.PUBLIC,\n editorialStatus: chapter.editorialStatus ?? TechnicalDocumentationEditorialStatus.APPROVED,\n assetRequests: [],\n });\n });\n\n return {\n units,\n plannedChapterRefsWithoutBody: plannedChapters\n .map((chapter) => chapter.chapterRef)\n .filter((chapterRef) => !(chapterRef in chapters))\n .sort(),\n authoredChapterRefsWithoutPlan,\n };\n}\n\n/**\n * Refuses a publication in which an authored chapter cites an API contract the rendered reference\n * does not carry.\n *\n * The engine's own pages DEGRADE such a link to plain text (#472), and for them that is right: the\n * engine hardcodes targets naming resources an application may switch off, so an absent target there\n * is a configuration fact. An application's chapter has no such excuse — its author wrote the\n * reference against THIS application, so an absent target is a typo, a renamed operation or a\n * removed one, and a guide telling a reader to call an operation that does not exist is exactly the\n * sentence this portal must never publish. So it fails, naming every dangling reference at once.\n *\n * Checked against the PUBLISHED bundle only: a withheld chapter never reaches a reader, and a\n * restricted one may legitimately cite a contract the public reference omits.\n */\nexport function assertApplicationDocumentationChapterApiReferencesResolve(\n publicBundle: TechnicalDocumentationAuthorizedBundleManifestV1,\n apiReferenceLinkIndex: ApiReferenceLinkIndex,\n): void {\n const dangling = publicBundle.units\n .filter((unit) => unit.unitRef.startsWith(APPLICATION_DOCUMENTATION_CHAPTER_UNIT_REF_PREFIX))\n .flatMap((unit) => unit.links\n .filter((link) => link.kind === TechnicalDocumentationLinkKind.API_REFERENCE && link.apiReferenceTarget !== null)\n .filter((link) => getTechnicalDocumentationApiReferenceTargetAvailability(apiReferenceLinkIndex, link.apiReferenceTarget!)\n === TechnicalDocumentationApiReferenceTargetAvailability.UNAVAILABLE)\n .map((link) => `${unit.unitRef} → \"${link.label}\" (${JSON.stringify(link.apiReferenceTarget)})`));\n if (dangling.length > 0) {\n throw new Error(\n `authored documentation chapter(s) cite API contracts this application's API reference does not publish: ${dangling.join('; ')}. `\n + 'Correct the resource or operation name in specifications/src/technical-documentation/index.ts.',\n );\n }\n}\n"]}
|
package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-domain-documentation.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-domain-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-domain-documentation.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/companion/application-documentation/application-domain-documentation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-domain-documentation.js","sourceRoot":"","sources":["../../../../src/companion/application-documentation/application-domain-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What THIS application is actually for.\n *\n * The documentation covered access, user administration, integrations, security and billing, and\n * said nothing about the product. A Wonder Todos customer could learn how to verify a webhook\n * signature before learning what a todo is — 104 published operations over the application's own\n * domain and not one page about them. The content module stated the omission as policy, which is\n * how it survived: a deliberate gap reads as a decision rather than a defect.\n *\n * Nothing here is authored per application, and nothing is inferred from a name. Every sentence\n * comes from a source the application already accepted:\n *\n * | what the page says | where it comes from |\n * | --- | --- |\n * | which resources are the product's domain | the application's own resource registry, not the core map |\n * | how they group, and what the group is called | `apiReferenceResourceCategories` in the app's tech-doc config |\n * | what each resource IS | the resource specification's `purpose`, carried on its OpenAPI tag |\n * | how it changes over time | the specification's lifecycle prose |\n * | who may do what to it | the resolved role list on each operation |\n *\n * The application/core split is what keeps this page from restating the rest of the site. An\n * application-owned resource has no framework page to belong to; a core one already has several.\n */\nexport const APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-domain' as const;\nexport const APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_VERSION = 1;\n\nexport interface ApplicationDomainOperationSource {\n readonly operationIdentifier: string;\n /** The operation's own summary, when its specification authored one. */\n readonly summary?: string;\n /** Labels of the organization roles that may call it, in the application's own words. */\n readonly roleLabels: readonly string[];\n /** True when the operation declares no required role — a real state, said explicitly. */\n readonly openToEveryMember: boolean;\n /** The method a client sends, e.g. `POST`. */\n readonly httpMethod?: string;\n /** The mounted path a client sends it to, parameters and all. */\n readonly path?: string;\n /**\n * One worked call, when the operation's specification authored one.\n *\n * A single example per RESOURCE reaches the page, not one per operation: the point is to show\n * what this application's payloads look like, and twenty near-identical bodies would bury the\n * page a reader came to for orientation. The API reference carries every operation's own.\n */\n readonly example?: {\n readonly title: string;\n readonly request?: unknown;\n readonly response?: unknown;\n };\n}\n\n/**\n * One connection between this resource and another, as a page may state it.\n *\n * `cascade` is the part that had to be earned rather than read off. The framework's own\n * `onParentDelete` lives under CHILD operations — it says what happens to the child when the\n * parent is deleted — but the fact is copied onto BOTH sides of the relationship, so a row alone\n * does not say which side this resource is on. Measured on a real application: the policy sits on\n * a many-side row 36 times and on a shape that resolves neither way 51 times.\n *\n * So the companion resolves the direction where the cardinality settles it (the ONE side of a\n * one-to-many is the parent, and the FK sits on the many side), and passes NOTHING where it does\n * not. A page that told somebody their data survives a delete when it does not is the most\n * expensive sentence this corpus could contain; an absent sentence costs a lookup.\n */\nexport interface ApplicationDomainRelationshipSource {\n readonly relatedResourceIdentifier: string;\n /** How many of the related thing participate, in consumer words. */\n readonly relatedCardinalityWords: string;\n /** What kind of link it is, in consumer words. */\n readonly natureWords: string;\n /** The field that carries the link, when one does. */\n readonly foreignKeyField?: string;\n /**\n * What a delete does, stated only when the direction is unambiguous AND a cascade is enabled.\n * Absent means \"not stated here\", never \"nothing happens\".\n */\n readonly cascade?: string;\n}\n\nexport interface ApplicationDomainResourceSource {\n readonly resourceIdentifier: string;\n /** The specification's `purpose`: what this thing IS, in the product's words. */\n readonly purpose?: string;\n /** The specification's account of how the resource changes over time. */\n readonly lifecycleRole?: string;\n readonly operations: readonly ApplicationDomainOperationSource[];\n readonly relationships?: readonly ApplicationDomainRelationshipSource[];\n}\n\nexport interface ApplicationDomainCategorySource {\n readonly id: string;\n /** The application's own name for this part of its domain, e.g. \"Work management\". */\n readonly label: string;\n readonly description?: string;\n readonly resources: readonly ApplicationDomainResourceSource[];\n}\n\nexport interface ApplicationDomainDocumentationSource {\n readonly applicationName: string;\n readonly categories: readonly ApplicationDomainCategorySource[];\n}\n\n/** Named presentations a page may request with `{{APPLICATION_DOMAIN:<selector>}}`. */\nexport enum ApplicationDomainPresentation {\n /** One line per thing the application manages, grouped the way the application groups it. */\n DOMAIN_OVERVIEW = 'domainOverview',\n /** Per resource: what it is, how it changes, and who may act on it. */\n DOMAIN_RESOURCE_DETAILS = 'domainResourceDetails',\n}\n\n/**\n * One complete page about one resource, ready to become a published unit.\n *\n * The projection emits the whole page rather than a fragment because the unit set is VARIABLE —\n * there is no authored Markdown for `todos` to carry a token, and there cannot be: the resources\n * are the application's, and an engine that authored a page per possible resource would be\n * authoring the application.\n */\nexport interface ApplicationDomainResourcePage {\n readonly resourceIdentifier: string;\n readonly title: string;\n /** A complete page body: `# Title` followed by `##` sections, as the engine content parser expects. */\n readonly markdown: string;\n}\n\nexport interface ApplicationDomainDocumentationFact {\n readonly sourceRef: string;\n readonly sourceVersion: number;\n readonly presentations: Readonly<Record<ApplicationDomainPresentation, string>>;\n readonly resourcePages: readonly ApplicationDomainResourcePage[];\n}\n\n/**\n * The sentence a page shows when an application publishes no domain of its own.\n *\n * Said explicitly rather than left blank, for the reason every empty inventory in this family is:\n * a reader who sees nothing cannot tell an application that manages nothing through its API from\n * documentation that failed to describe it.\n */\nconst NO_DOMAIN_MESSAGE = 'publishes no resources of its own through its API, so everything it exposes is described by the framework pages in this documentation.';\n\nfunction whoMayAct(operation: ApplicationDomainOperationSource): string {\n if (operation.openToEveryMember) return 'Any active member';\n if (operation.roleLabels.length === 0) return 'Not published for organization roles';\n return operation.roleLabels.join(', ');\n}\n\nfunction domainOverviewMarkdown(source: ApplicationDomainDocumentationSource): string {\n if (source.categories.length === 0) return `${source.applicationName} ${NO_DOMAIN_MESSAGE}`;\n const blocks = source.categories.map((category) => {\n const heading = category.description === undefined\n ? `### ${category.label}`\n : `### ${category.label}\\n\\n${category.description}`;\n const rows = category.resources\n .map((resource) => {\n // Linked, because each resource now HAS a page. The link text stays the API's own name so\n // a reader can match it against a payload, an error message or the reference.\n const name = `[\\`${resource.resourceIdentifier}\\`](/what-this-application-manages/${applicationDomainResourcePageSlug(resource.resourceIdentifier)})`;\n return `| ${name} | ${resource.purpose ?? 'Not described by its specification.'} |`;\n })\n .join('\\n');\n return `${heading}\\n\\n| Resource | What it is |\\n| --- | --- |\\n${rows}`;\n });\n return `${blocks.join('\\n\\n')}\\n\\nEach name above is the one the API uses, so it is also what you will find in the API reference and in any tool or webhook payload that mentions it.`;\n}\n\nfunction domainResourceDetailsMarkdown(source: ApplicationDomainDocumentationSource): string {\n if (source.categories.length === 0) return `${source.applicationName} ${NO_DOMAIN_MESSAGE}`;\n const blocks: string[] = [];\n for (const category of source.categories) {\n for (const resource of category.resources) {\n const lines = [`### \\`${resource.resourceIdentifier}\\``, ''];\n if (resource.purpose !== undefined) lines.push(resource.purpose, '');\n if (resource.lifecycleRole !== undefined) lines.push(resource.lifecycleRole, '');\n if (resource.operations.length === 0) {\n lines.push('This resource publishes no operations a client may call directly.');\n } else {\n lines.push('| Operation | What it does | Who may call it |', '| --- | --- | --- |');\n for (const operation of resource.operations) {\n lines.push(`| \\`${operation.operationIdentifier}\\` | ${operation.summary ?? '—'} | ${whoMayAct(operation)} |`);\n }\n }\n blocks.push(lines.join('\\n').trim());\n }\n }\n return `${blocks.join('\\n\\n')}\\n\\nA role higher in the inheritance chain can do everything the roles below it can, so a role that is not named here may still qualify through the role it includes. The API reference carries each operation's exact arguments and responses.`;\n}\n\n/** The route every generated resource page lives at, and the only place that shape is written. */\nexport function applicationDomainResourcePageSlug(resourceIdentifier: string): string {\n return resourceIdentifier;\n}\n\nfunction jsonBlock(label: string, value: unknown): string[] {\n return ['', `**${label}**`, '', '~~~json', JSON.stringify(value, null, 2), '~~~'];\n}\n\nfunction operationsTable(resource: ApplicationDomainResourceSource): string[] {\n if (resource.operations.length === 0) {\n return ['This resource publishes no operations a client may call directly.'];\n }\n /*\n * The `Send` column only appears when at least one operation resolved a method and a path. A\n * column of dashes is worse than no column: it reads as \"this cannot be called\" rather than\n * \"this projection did not resolve it\".\n */\n const anyWire = resource.operations.some((operation) => operation.httpMethod !== undefined && operation.path !== undefined);\n const columns = anyWire\n ? ['Operation', 'What it does', 'Send', 'Who may call it']\n : ['Operation', 'What it does', 'Who may call it'];\n const header = [`| ${columns.join(' | ')} |`, `| ${columns.map(() => '---').join(' | ')} |`];\n const rows = resource.operations.map((operation) => {\n const wire = operation.httpMethod !== undefined && operation.path !== undefined\n ? `\\`${operation.httpMethod} ${operation.path}\\``\n : '—';\n const cells = anyWire\n ? [`\\`${operation.operationIdentifier}\\``, operation.summary ?? '—', wire, whoMayAct(operation)]\n : [`\\`${operation.operationIdentifier}\\``, operation.summary ?? '—', whoMayAct(operation)];\n return `| ${cells.join(' | ')} |`;\n });\n return [...header, ...rows];\n}\n\n/**\n * Builds the page for one resource.\n *\n * Deliberately NOT a summary of the API reference. The reference answers \"what are this\n * operation's exact arguments\"; this page answers \"what is this thing, what can I do with it, and\n * may I\". So it carries the specification's own prose, one worked call, and a route onward — and\n * refuses to restate field tables that would go stale the moment a schema moves.\n */\nfunction resourcePageMarkdown(\n applicationName: string,\n category: ApplicationDomainCategorySource,\n resource: ApplicationDomainResourceSource,\n describedResourceIdentifiers: ReadonlySet<string>,\n): string {\n const lines: string[] = [`# ${resource.resourceIdentifier}`, ''];\n lines.push(resource.purpose ?? `\\`${resource.resourceIdentifier}\\` is published by ${applicationName} under ${category.label}. Its specification authored no description, so this page can only show what the application exposes.`);\n /*\n * The purpose is the page's opening line, which the engine content parser reads as the unit\n * SUMMARY — so it becomes the description in navigation and search, which is exactly what a\n * one-line \"what is this thing\" belongs in. The lifecycle then gets its own section, under a\n * heading that says what it actually answers.\n */\n lines.push('', '## How it changes', '');\n lines.push(resource.lifecycleRole ?? 'Its specification does not describe how it changes over time.');\n lines.push('', '## What you can do', '', ...operationsTable(resource));\n\n const relationships = resource.relationships ?? [];\n if (relationships.length > 0) {\n lines.push('', '## What it connects to', '');\n const anyCascade = relationships.some((relationship) => relationship.cascade !== undefined);\n const columns = anyCascade\n ? ['Related', 'How many', 'Link', 'Field', 'When something is deleted']\n : ['Related', 'How many', 'Link', 'Field'];\n lines.push(`| ${columns.join(' | ')} |`, `| ${columns.map(() => '---').join(' | ')} |`);\n for (const relationship of relationships) {\n /*\n * Linked only when the related resource HAS a page. A domain resource usually relates\n * outward as well — every one is organization-scoped, and many point at a user — and those\n * facts belong on the page even though the framework, not this section, documents them.\n * Dropping them was the first cut and it was wrong: Wonder CRM's `deal` relates to\n * `organizations` and `users` and to none of its own resources, so an owned-only filter left\n * the section empty on a resource that has two real connections.\n */\n const name = describedResourceIdentifiers.has(relationship.relatedResourceIdentifier)\n ? `[\\`${relationship.relatedResourceIdentifier}\\`](/what-this-application-manages/${applicationDomainResourcePageSlug(relationship.relatedResourceIdentifier)})`\n : `\\`${relationship.relatedResourceIdentifier}\\``;\n const cells = [\n name,\n relationship.relatedCardinalityWords,\n relationship.natureWords,\n relationship.foreignKeyField === undefined ? '—' : `\\`${relationship.foreignKeyField}\\``,\n ];\n if (anyCascade) cells.push(relationship.cascade ?? 'Not stated here');\n lines.push(`| ${cells.join(' | ')} |`);\n }\n if (anyCascade) {\n lines.push(\n '',\n 'An empty **When something is deleted** cell means this page does not state it, not that nothing happens — the relationship is one whose direction the documentation cannot resolve on its own. Check the operation contract before relying on a delete either way.',\n );\n }\n }\n\n const exampleOperation = resource.operations.find((operation) => operation.example !== undefined);\n if (exampleOperation?.example !== undefined) {\n const { example } = exampleOperation;\n lines.push('', `## Worked example: \\`${exampleOperation.operationIdentifier}\\``, '', example.title);\n if (example.request !== undefined) lines.push(...jsonBlock('Request', example.request));\n if (example.response !== undefined) lines.push(...jsonBlock('Response', example.response));\n lines.push('', 'Identifiers and values above are illustrative; every field is defined in the API reference.');\n }\n\n lines.push(\n '',\n '## Where to go next',\n '',\n '| You need to | Go to |',\n '| --- | --- |',\n '| The exact fields, arguments and responses | [API reference](/api) |',\n '| To call this from your own code | [Send your first API request](/integrations/rest/send-request) |',\n '| To be told when one changes | [Webhooks](/integrations/webhooks) |',\n `| Everything else this application manages | [What ${applicationName} manages](/what-this-application-manages) |`,\n );\n return lines.join('\\n');\n}\n\nfunction resourcePages(source: ApplicationDomainDocumentationSource): ApplicationDomainResourcePage[] {\n // Exactly the resources this projection gives a page, which is what a link may point at.\n const describedResourceIdentifiers = new Set(\n source.categories.flatMap((category) => category.resources.map((resource) => resource.resourceIdentifier)),\n );\n const pages: ApplicationDomainResourcePage[] = [];\n for (const category of source.categories) {\n for (const resource of category.resources) {\n pages.push({\n resourceIdentifier: resource.resourceIdentifier,\n title: resource.resourceIdentifier,\n markdown: resourcePageMarkdown(source.applicationName, category, resource, describedResourceIdentifiers),\n });\n }\n }\n return pages;\n}\n\n/**\n * Projects the application's own domain. A pure function of the source, so two runs over the same\n * application produce identical bytes.\n */\nexport function projectApplicationDomainDocumentation(\n source: ApplicationDomainDocumentationSource,\n): ApplicationDomainDocumentationFact {\n if (source.applicationName.trim().length === 0) {\n throw new Error('application domain projection requires a customer-facing application name');\n }\n const seenResources = new Set<string>();\n for (const category of source.categories) {\n if (category.label.trim().length === 0) {\n throw new Error(`application domain projection received category '${category.id}' with no label`);\n }\n for (const resource of category.resources) {\n if (resource.resourceIdentifier.trim().length === 0) {\n throw new Error('application domain projection received a resource with no identifier');\n }\n // A resource belongs to exactly one part of the domain. Two categories claiming the same one\n // would describe it twice with no way for a reader to tell which reading is current — and the\n // config's own contract is that every published resource is listed exactly once.\n if (seenResources.has(resource.resourceIdentifier)) {\n throw new Error(`application domain projection received resource '${resource.resourceIdentifier}' in more than one category`);\n }\n seenResources.add(resource.resourceIdentifier);\n }\n }\n return {\n sourceRef: APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_REF,\n sourceVersion: APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_VERSION,\n presentations: Object.freeze({\n [ApplicationDomainPresentation.DOMAIN_OVERVIEW]: domainOverviewMarkdown(source),\n [ApplicationDomainPresentation.DOMAIN_RESOURCE_DETAILS]: domainResourceDetailsMarkdown(source),\n }),\n resourcePages: resourcePages(source),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"application-domain-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-domain-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What THIS application is actually for.\n *\n * The documentation covered access, user administration, integrations, security and billing, and\n * said nothing about the product. A Wonder Todos customer could learn how to verify a webhook\n * signature before learning what a todo is — 104 published operations over the application's own\n * domain and not one page about them. The content module stated the omission as policy, which is\n * how it survived: a deliberate gap reads as a decision rather than a defect.\n *\n * Nothing here is authored per application, and nothing is inferred from a name. Every sentence\n * comes from a source the application already accepted:\n *\n * | what the page says | where it comes from |\n * | --- | --- |\n * | which resources are the product's domain | the application's own resource registry, not the core map |\n * | how they group, and what the group is called | `apiReferenceResourceCategories` in the app's tech-doc config |\n * | what each resource IS | the resource specification's `purpose`, carried on its OpenAPI tag |\n * | how it changes over time | the specification's lifecycle prose |\n * | who may do what to it | the resolved role list on each operation |\n *\n * The application/core split is what keeps this page from restating the rest of the site. An\n * application-owned resource has no framework page to belong to; a core one already has several.\n */\nexport const APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-domain' as const;\nexport const APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_VERSION = 1;\n\nexport interface ApplicationDomainOperationSource {\n readonly operationIdentifier: string;\n /** The operation's own summary, when its specification authored one. */\n readonly summary?: string;\n /** Labels of the organization roles that may call it, in the application's own words. */\n readonly roleLabels: readonly string[];\n /** True when the operation declares no required role — a real state, said explicitly. */\n readonly openToEveryMember: boolean;\n /** The method a client sends, e.g. `POST`. */\n readonly httpMethod?: string;\n /** The mounted path a client sends it to, parameters and all. */\n readonly path?: string;\n /**\n * One worked call, when the operation's specification authored one.\n *\n * A single example per RESOURCE reaches the page, not one per operation: the point is to show\n * what this application's payloads look like, and twenty near-identical bodies would bury the\n * page a reader came to for orientation. The API reference carries every operation's own.\n */\n readonly example?: {\n readonly title: string;\n readonly request?: unknown;\n readonly response?: unknown;\n };\n}\n\n/**\n * One connection between this resource and another, as a page may state it.\n *\n * `cascade` is the part that had to be earned rather than read off. The framework's own\n * `onParentDelete` lives under CHILD operations — it says what happens to the child when the\n * parent is deleted — but the fact is copied onto BOTH sides of the relationship, so a row alone\n * does not say which side this resource is on. Measured on a real application: the policy sits on\n * a many-side row 36 times and on a shape that resolves neither way 51 times.\n *\n * So the companion resolves the direction where the cardinality settles it (the ONE side of a\n * one-to-many is the parent, and the FK sits on the many side), and passes NOTHING where it does\n * not. A page that told somebody their data survives a delete when it does not is the most\n * expensive sentence this corpus could contain; an absent sentence costs a lookup.\n */\nexport interface ApplicationDomainRelationshipSource {\n readonly relatedResourceIdentifier: string;\n /** How many of the related thing participate, in consumer words. */\n readonly relatedCardinalityWords: string;\n /** What kind of link it is, in consumer words. */\n readonly natureWords: string;\n /** The field that carries the link, when one does. */\n readonly foreignKeyField?: string;\n /**\n * What a delete does, stated only when the direction is unambiguous AND a cascade is enabled.\n * Absent means \"not stated here\", never \"nothing happens\".\n */\n readonly cascade?: string;\n}\n\nexport interface ApplicationDomainResourceSource {\n readonly resourceIdentifier: string;\n /** The specification's `purpose`: what this thing IS, in the product's words. */\n readonly purpose?: string;\n /** The specification's account of how the resource changes over time. */\n readonly lifecycleRole?: string;\n readonly operations: readonly ApplicationDomainOperationSource[];\n readonly relationships?: readonly ApplicationDomainRelationshipSource[];\n}\n\nexport interface ApplicationDomainCategorySource {\n readonly id: string;\n /** The application's own name for this part of its domain, e.g. \"Work management\". */\n readonly label: string;\n readonly description?: string;\n readonly resources: readonly ApplicationDomainResourceSource[];\n}\n\nexport interface ApplicationDomainDocumentationSource {\n readonly applicationName: string;\n readonly categories: readonly ApplicationDomainCategorySource[];\n}\n\n/** Named presentations a page may request with `{{APPLICATION_DOMAIN:<selector>}}`. */\nexport enum ApplicationDomainPresentation {\n /** One line per thing the application manages, grouped the way the application groups it. */\n DOMAIN_OVERVIEW = 'domainOverview',\n /** Per resource: what it is, how it changes, and who may act on it. */\n DOMAIN_RESOURCE_DETAILS = 'domainResourceDetails',\n}\n\n/**\n * One complete page about one resource, ready to become a published unit.\n *\n * The projection emits the whole page rather than a fragment because the unit set is VARIABLE —\n * there is no authored Markdown for `todos` to carry a token, and there cannot be: the resources\n * are the application's, and an engine that authored a page per possible resource would be\n * authoring the application.\n */\nexport interface ApplicationDomainResourcePage {\n readonly resourceIdentifier: string;\n readonly title: string;\n /** A complete page body: `# Title` followed by `##` sections, as the engine content parser expects. */\n readonly markdown: string;\n}\n\nexport interface ApplicationDomainDocumentationFact {\n readonly sourceRef: string;\n readonly sourceVersion: number;\n readonly presentations: Readonly<Record<ApplicationDomainPresentation, string>>;\n readonly resourcePages: readonly ApplicationDomainResourcePage[];\n}\n\n/**\n * The sentence a page shows when an application publishes no domain of its own.\n *\n * Said explicitly rather than left blank, for the reason every empty inventory in this family is:\n * a reader who sees nothing cannot tell an application that manages nothing through its API from\n * documentation that failed to describe it.\n */\nconst NO_DOMAIN_MESSAGE = 'publishes no resources of its own through its API, so everything it exposes is described by the framework pages in this documentation.';\n\nfunction whoMayAct(operation: ApplicationDomainOperationSource): string {\n if (operation.openToEveryMember) return 'Any active member';\n if (operation.roleLabels.length === 0) return 'Not published for organization roles';\n return operation.roleLabels.join(', ');\n}\n\nfunction domainOverviewMarkdown(source: ApplicationDomainDocumentationSource): string {\n if (source.categories.length === 0) return `${source.applicationName} ${NO_DOMAIN_MESSAGE}`;\n const blocks = source.categories.map((category) => {\n const heading = category.description === undefined\n ? `### ${category.label}`\n : `### ${category.label}\\n\\n${category.description}`;\n const rows = category.resources\n .map((resource) => {\n // Linked, because each resource now HAS a page. The link text stays the API's own name so\n // a reader can match it against a payload, an error message or the reference.\n const name = `[\\`${resource.resourceIdentifier}\\`](/what-this-application-manages/${applicationDomainResourcePageSlug(resource.resourceIdentifier)})`;\n return `| ${name} | ${resource.purpose ?? 'Not described by its specification.'} |`;\n })\n .join('\\n');\n return `${heading}\\n\\n| Resource | What it is |\\n| --- | --- |\\n${rows}`;\n });\n return `${blocks.join('\\n\\n')}\\n\\nEach name above is the one the API uses, so it is also what you will find in the API reference and in any tool or webhook payload that mentions it.`;\n}\n\nfunction domainResourceDetailsMarkdown(source: ApplicationDomainDocumentationSource): string {\n if (source.categories.length === 0) return `${source.applicationName} ${NO_DOMAIN_MESSAGE}`;\n const blocks: string[] = [];\n for (const category of source.categories) {\n for (const resource of category.resources) {\n const lines = [`### \\`${resource.resourceIdentifier}\\``, ''];\n if (resource.purpose !== undefined) lines.push(resource.purpose, '');\n if (resource.lifecycleRole !== undefined) lines.push(resource.lifecycleRole, '');\n if (resource.operations.length === 0) {\n lines.push('This resource publishes no operations a client may call directly.');\n } else {\n lines.push('| Operation | What it does | Who may call it |', '| --- | --- | --- |');\n for (const operation of resource.operations) {\n lines.push(`| \\`${operation.operationIdentifier}\\` | ${operation.summary ?? '—'} | ${whoMayAct(operation)} |`);\n }\n }\n blocks.push(lines.join('\\n').trim());\n }\n }\n return `${blocks.join('\\n\\n')}\\n\\nA role higher in the inheritance chain can do everything the roles below it can, so a role that is not named here may still qualify through the role it includes. The API reference carries each operation's exact arguments and responses.`;\n}\n\n/** The route every generated resource page lives at, and the only place that shape is written. */\nexport function applicationDomainResourcePageSlug(resourceIdentifier: string): string {\n return resourceIdentifier;\n}\n\nfunction jsonBlock(label: string, value: unknown): string[] {\n return ['', `**${label}**`, '', '~~~json', JSON.stringify(value, null, 2), '~~~'];\n}\n\nfunction operationsTable(resource: ApplicationDomainResourceSource): string[] {\n if (resource.operations.length === 0) {\n return ['This resource publishes no operations a client may call directly.'];\n }\n /*\n * The `Send` column only appears when at least one operation resolved a method and a path. A\n * column of dashes is worse than no column: it reads as \"this cannot be called\" rather than\n * \"this projection did not resolve it\".\n */\n const anyWire = resource.operations.some((operation) => operation.httpMethod !== undefined && operation.path !== undefined);\n const columns = anyWire\n ? ['Operation', 'What it does', 'Send', 'Who may call it']\n : ['Operation', 'What it does', 'Who may call it'];\n const header = [`| ${columns.join(' | ')} |`, `| ${columns.map(() => '---').join(' | ')} |`];\n const rows = resource.operations.map((operation) => {\n const wire = operation.httpMethod !== undefined && operation.path !== undefined\n ? `\\`${operation.httpMethod} ${operation.path}\\``\n : '—';\n const cells = anyWire\n ? [`\\`${operation.operationIdentifier}\\``, operation.summary ?? '—', wire, whoMayAct(operation)]\n : [`\\`${operation.operationIdentifier}\\``, operation.summary ?? '—', whoMayAct(operation)];\n return `| ${cells.join(' | ')} |`;\n });\n return [...header, ...rows];\n}\n\n/**\n * Builds the page for one resource.\n *\n * Deliberately NOT a summary of the API reference. The reference answers \"what are this\n * operation's exact arguments\"; this page answers \"what is this thing, what can I do with it, and\n * may I\". So it carries the specification's own prose, one worked call, and a route onward — and\n * refuses to restate field tables that would go stale the moment a schema moves.\n */\nfunction resourcePageMarkdown(\n applicationName: string,\n category: ApplicationDomainCategorySource,\n resource: ApplicationDomainResourceSource,\n describedResourceIdentifiers: ReadonlySet<string>,\n): string {\n const lines: string[] = [`# ${resource.resourceIdentifier}`, ''];\n lines.push(resource.purpose ?? `\\`${resource.resourceIdentifier}\\` is published by ${applicationName} under ${category.label}. Its specification authored no description, so this page can only show what the application exposes.`);\n /*\n * The purpose is the page's opening line, which the engine content parser reads as the unit\n * SUMMARY — so it becomes the description in navigation and search, which is exactly what a\n * one-line \"what is this thing\" belongs in. The lifecycle then gets its own section, under a\n * heading that says what it actually answers.\n */\n lines.push('', '## How it changes', '');\n lines.push(resource.lifecycleRole ?? 'Its specification does not describe how it changes over time.');\n lines.push('', '## What you can do', '', ...operationsTable(resource));\n\n const relationships = resource.relationships ?? [];\n if (relationships.length > 0) {\n lines.push('', '## What it connects to', '');\n const anyCascade = relationships.some((relationship) => relationship.cascade !== undefined);\n const columns = anyCascade\n ? ['Related', 'How many', 'Link', 'Field', 'When something is deleted']\n : ['Related', 'How many', 'Link', 'Field'];\n lines.push(`| ${columns.join(' | ')} |`, `| ${columns.map(() => '---').join(' | ')} |`);\n for (const relationship of relationships) {\n /*\n * Linked only when the related resource HAS a page. A domain resource usually relates\n * outward as well — every one is organization-scoped, and many point at a user — and those\n * facts belong on the page even though the framework, not this section, documents them.\n * Dropping them was the first cut and it was wrong: Wonder CRM's `deal` relates to\n * `organizations` and `users` and to none of its own resources, so an owned-only filter left\n * the section empty on a resource that has two real connections.\n */\n const name = describedResourceIdentifiers.has(relationship.relatedResourceIdentifier)\n ? `[\\`${relationship.relatedResourceIdentifier}\\`](/what-this-application-manages/${applicationDomainResourcePageSlug(relationship.relatedResourceIdentifier)})`\n : `\\`${relationship.relatedResourceIdentifier}\\``;\n const cells = [\n name,\n relationship.relatedCardinalityWords,\n relationship.natureWords,\n relationship.foreignKeyField === undefined ? '—' : `\\`${relationship.foreignKeyField}\\``,\n ];\n if (anyCascade) cells.push(relationship.cascade ?? 'Not stated here');\n lines.push(`| ${cells.join(' | ')} |`);\n }\n if (anyCascade) {\n lines.push(\n '',\n 'An empty **When something is deleted** cell means this page does not state it, not that nothing happens — the relationship is one whose direction the documentation cannot resolve on its own. Check the operation contract before relying on a delete either way.',\n );\n }\n }\n\n const exampleOperation = resource.operations.find((operation) => operation.example !== undefined);\n if (exampleOperation?.example !== undefined) {\n const { example } = exampleOperation;\n lines.push('', `## Worked example: \\`${exampleOperation.operationIdentifier}\\``, '', example.title);\n if (example.request !== undefined) lines.push(...jsonBlock('Request', example.request));\n if (example.response !== undefined) lines.push(...jsonBlock('Response', example.response));\n lines.push('', 'Identifiers and values above are illustrative; every field is defined in the API reference.');\n }\n\n lines.push(\n '',\n '## Where to go next',\n '',\n '| You need to | Go to |',\n '| --- | --- |',\n '| The exact fields, arguments and responses | [API reference](/api) |',\n '| To call this from your own code | [Send your first API request](/integrations/rest/send-request) |',\n '| To be told when one changes | [Webhooks](/integrations/webhooks) |',\n `| Everything else this application manages | [What ${applicationName} manages](/what-this-application-manages) |`,\n );\n return lines.join('\\n');\n}\n\nfunction resourcePages(source: ApplicationDomainDocumentationSource): ApplicationDomainResourcePage[] {\n // Exactly the resources this projection gives a page, which is what a link may point at.\n const describedResourceIdentifiers = new Set(\n source.categories.flatMap((category) => category.resources.map((resource) => resource.resourceIdentifier)),\n );\n const pages: ApplicationDomainResourcePage[] = [];\n for (const category of source.categories) {\n for (const resource of category.resources) {\n pages.push({\n resourceIdentifier: resource.resourceIdentifier,\n title: resource.resourceIdentifier,\n markdown: resourcePageMarkdown(source.applicationName, category, resource, describedResourceIdentifiers),\n });\n }\n }\n return pages;\n}\n\n/**\n * Projects the application's own domain. A pure function of the source, so two runs over the same\n * application produce identical bytes.\n */\nexport function projectApplicationDomainDocumentation(\n source: ApplicationDomainDocumentationSource,\n): ApplicationDomainDocumentationFact {\n if (source.applicationName.trim().length === 0) {\n throw new Error('application domain projection requires a customer-facing application name');\n }\n const seenResources = new Set<string>();\n for (const category of source.categories) {\n if (category.label.trim().length === 0) {\n throw new Error(`application domain projection received category '${category.id}' with no label`);\n }\n for (const resource of category.resources) {\n if (resource.resourceIdentifier.trim().length === 0) {\n throw new Error('application domain projection received a resource with no identifier');\n }\n // A resource belongs to exactly one part of the domain. Two categories claiming the same one\n // would describe it twice with no way for a reader to tell which reading is current — and the\n // config's own contract is that every published resource is listed exactly once.\n if (seenResources.has(resource.resourceIdentifier)) {\n throw new Error(`application domain projection received resource '${resource.resourceIdentifier}' in more than one category`);\n }\n seenResources.add(resource.resourceIdentifier);\n }\n }\n return {\n sourceRef: APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_REF,\n sourceVersion: APPLICATION_DOMAIN_DOCUMENTATION_SOURCE_VERSION,\n presentations: Object.freeze({\n [ApplicationDomainPresentation.DOMAIN_OVERVIEW]: domainOverviewMarkdown(source),\n [ApplicationDomainPresentation.DOMAIN_RESOURCE_DETAILS]: domainResourceDetailsMarkdown(source),\n }),\n resourcePages: resourcePages(source),\n };\n}\n"]}
|
package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-integration-documentation.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-integration-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-integration-documentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gDAAgD,EAAG,qDAA8D,CAAC;AAC/H,eAAO,MAAM,oDAAoD,IAAI,CAAC;AAEtE,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,yCAAyC;IACxD,QAAQ,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACvD,QAAQ,CAAC,aAAa,EAAE,SAAS,6BAA6B,EAAE,CAAC;CAClE;AAED,4FAA4F;AAC5F,oBAAY,kCAAkC;IAC5C,4DAA4D;IAC5D,SAAS,aAAa;IACtB,2EAA2E;IAC3E,cAAc,kBAAkB;CACjC;AAED,MAAM,WAAW,uCAAuC;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC,CAAC;CACtF;AAsBD;;;GAGG;AACH,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,yCAAyC,GAChD,uCAAuC,CAsCzC"}
|
package/dist/esm/companion/application-documentation/application-integration-documentation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-integration-documentation.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-integration-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-integration-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tools an MCP client will find, and the events a webhook receiver will be sent.\n *\n * Five webhook pages explained delivery, verification, retries and reconciliation without ever\n * naming an event, and the MCP page described a catalogue without naming a tool in it. Both\n * inventories were already being computed — as booleans, to decide whether those pages publish at\n * all — so the reader was one projection away from the list the whole time.\n *\n * Names are the application's own: a tool is `<resource>__<operation>` exactly as an agent must\n * type it, and an event names the resource and operation that produce it. Nothing here is\n * humanized, because every one of these strings is a value someone matches on in code.\n */\nexport const APPLICATION_INTEGRATION_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-integration' as const;\nexport const APPLICATION_INTEGRATION_DOCUMENTATION_SOURCE_VERSION = 1;\n\nexport interface ApplicationMcpToolSource {\n /** The exact name an agent calls, `<resource>__<operation>`. */\n readonly toolName: string;\n readonly resourceIdentifier: string;\n readonly operationIdentifier: string;\n}\n\nexport interface ApplicationWebhookEventSource {\n readonly resourceIdentifier: string;\n readonly operationIdentifier: string;\n /** The notification channel that carries it, which is also its delivery scope. */\n readonly channel: string;\n}\n\nexport interface ApplicationIntegrationDocumentationSource {\n readonly mcpTools: readonly ApplicationMcpToolSource[];\n readonly webhookEvents: readonly ApplicationWebhookEventSource[];\n}\n\n/** Named presentations a page may request with `{{APPLICATION_INTEGRATION:<selector>}}`. */\nexport enum ApplicationIntegrationPresentation {\n /** Every tool this application publishes to MCP clients. */\n MCP_TOOLS = 'mcpTools',\n /** Every resource operation that produces an outbound webhook delivery. */\n WEBHOOK_EVENTS = 'webhookEvents',\n}\n\nexport interface ApplicationIntegrationDocumentationFact {\n readonly sourceRef: string;\n readonly sourceVersion: number;\n readonly presentations: Readonly<Record<ApplicationIntegrationPresentation, string>>;\n}\n\nfunction mcpToolsMarkdown(source: ApplicationIntegrationDocumentationSource): string {\n if (source.mcpTools.length === 0) {\n return 'This application publishes no MCP tools, so a connected client will find an empty catalogue.';\n }\n const rows = source.mcpTools\n .map((tool) => `| \\`${tool.toolName}\\` | ${tool.resourceIdentifier} | ${tool.operationIdentifier} |`)\n .join('\\n');\n return `| Tool | Resource | Operation |\\n| --- | --- | --- |\\n${rows}\\n\\nThese are the tools the application publishes. What YOU see is the subset your credential is allowed to call, so a shorter catalogue is an authorization result and not a fault. The API reference carries each operation's exact arguments and response.`;\n}\n\nfunction webhookEventsMarkdown(source: ApplicationIntegrationDocumentationSource): string {\n if (source.webhookEvents.length === 0) {\n return 'This application declares no outbound webhook events, so an endpoint would receive nothing even when one is configured and enabled.';\n }\n const rows = source.webhookEvents\n .map((event) => `| ${event.resourceIdentifier} | ${event.operationIdentifier} | \\`${event.channel}\\` |`)\n .join('\\n');\n return `| Resource | Operation that fires it | Channel |\\n| --- | --- | --- |\\n${rows}\\n\\nEvery enabled endpoint on the matching channel receives every event on that channel: an endpoint is not subscribed to a subset. Route on the signed \\`resourceIdentifier\\` and \\`operationIdentifier\\` claims rather than on the destination URL, and ignore an event your receiver does not handle.`;\n}\n\n/**\n * Projects both integration inventories. A pure function of the source, so two runs over the same\n * application produce identical bytes.\n */\nexport function projectApplicationIntegrationDocumentation(\n source: ApplicationIntegrationDocumentationSource,\n): ApplicationIntegrationDocumentationFact {\n /*\n * Both inventories are ADDRESSES: a tool name is what an agent types, and a (resource, operation,\n * channel) triple is one fact about one delivery. Neither can legitimately appear twice, so a\n * repeat is a producer walking something twice — which is exactly what the companion's collector\n * did, visiting every selected core resource once from the prepared list and once from the core\n * factory sweep. It survived because the collector used to answer a boolean, where duplicates are\n * unobservable.\n *\n * The refusal lives HERE rather than only in that collector because this is the one place every\n * producer passes through, and a duplicated row is worse than a loud failure: it reads as two\n * separate things a reader must tell apart.\n */\n const seenToolNames = new Set<string>();\n for (const tool of source.mcpTools) {\n if (tool.toolName.trim().length === 0) throw new Error('application integration projection received an MCP tool with no name');\n if (seenToolNames.has(tool.toolName)) {\n throw new Error(`application integration projection received the MCP tool '${tool.toolName}' twice — a tool name addresses one operation`);\n }\n seenToolNames.add(tool.toolName);\n }\n const seenEvents = new Set<string>();\n for (const event of source.webhookEvents) {\n if (event.channel.trim().length === 0) throw new Error('application integration projection received a webhook event with no channel');\n const identity = `${event.resourceIdentifier}.${event.operationIdentifier}.${event.channel}`;\n if (seenEvents.has(identity)) {\n throw new Error(`application integration projection received the webhook event '${identity}' twice — one operation on one channel is one event`);\n }\n seenEvents.add(identity);\n }\n return {\n sourceRef: APPLICATION_INTEGRATION_DOCUMENTATION_SOURCE_REF,\n sourceVersion: APPLICATION_INTEGRATION_DOCUMENTATION_SOURCE_VERSION,\n presentations: Object.freeze({\n [ApplicationIntegrationPresentation.MCP_TOOLS]: mcpToolsMarkdown(source),\n [ApplicationIntegrationPresentation.WEBHOOK_EVENTS]: webhookEventsMarkdown(source),\n }),\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-organization-role-documentation.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-organization-role-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-organization-role-documentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-organization-role-documentation.js","sourceRoot":"","sources":["../../../../src/companion/application-documentation/application-organization-role-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CORE_ORG_ROLES,\n DEFAULT_ORGANIZATION_ROLES,\n ResourcePrimaryScope,\n} from '@wildo-ai/saas-models';\nimport {\n} from '@wildo-ai/saas-specifications/technical-documentation';\n\nimport type { ApplicationOrganizationRolesDocumentationFact } from './technical-documentation-engine-content-bundle';\n\nexport const APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:organization-roles' as const;\n/** Advances when this projection's shape changes; it is the fact's version wherever provenance cites it. */\nexport const APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_VERSION = 1;\n\n/** Minimal application/engine role specification needed by consumer documentation. */\nexport interface ApplicationRoleDocumentationSource {\n readonly ref: string;\n readonly purpose: string | null;\n readonly businessRole: string | null;\n readonly authorityBoundary: string | null;\n readonly useWhen: string | null;\n readonly avoidWhen: string | null;\n readonly businessConstraints: readonly string[] | null;\n}\n\n/**\n * Application-independent organization-role projection before UI labels are\n * joined. The introspection subprocess can safely emit this JSON-only shape;\n * the parent companion later joins the application's primary-locale labels.\n */\nexport interface ApplicationOrganizationRoleDocumentationSource {\n readonly role: string;\n readonly inheritFrom: string | null;\n readonly purpose: string;\n readonly businessRole: string | null;\n readonly authorityBoundary: string;\n readonly useWhen: string;\n readonly avoidWhen: string;\n readonly businessConstraints: readonly string[];\n}\n\n/** Complete consumer-visible role documentation after the application label join. */\nexport interface ApplicationOrganizationRoleDocumentation extends ApplicationOrganizationRoleDocumentationSource {\n readonly label: string;\n readonly description: string;\n}\n\ninterface ApplicationRoleConfigurationProjectionInput {\n readonly role?: string;\n readonly inheritFrom?: string;\n readonly relatedPrimaryScope: ResourcePrimaryScope;\n}\n\n/**\n * Index companion-exported role specifications by their runtime role token.\n * Engine and application-defined roles intentionally share this namespace.\n */\nexport function indexApplicationRoleDocumentationSources(\n roleSpecifications: Record<string, unknown> | undefined,\n): ReadonlyMap<string, ApplicationRoleDocumentationSource> {\n const result = new Map<string, ApplicationRoleDocumentationSource>();\n for (const candidate of Object.values(roleSpecifications ?? {})) {\n if (!isPlainObject(candidate) || typeof candidate.ref !== 'string' || candidate.ref.length === 0) continue;\n if (result.has(candidate.ref)) {\n throw new Error(`application organization-role projector: duplicate role specification for '${candidate.ref}'`);\n }\n result.set(candidate.ref, {\n ref: candidate.ref,\n purpose: nonEmptyStringOrNull(candidate.purpose),\n businessRole: nonEmptyStringOrNull(candidate.businessRole),\n authorityBoundary: nonEmptyStringOrNull(candidate.authorityBoundary),\n useWhen: nonEmptyStringOrNull(candidate.useWhen),\n avoidWhen: nonEmptyStringOrNull(candidate.avoidWhen),\n businessConstraints: nonEmptyStringArrayOrNull(candidate.businessConstraints),\n });\n }\n return result;\n}\n\n/**\n * Resolve every framework and application-defined organization role from the\n * application's merged runtime registry and authored role specifications.\n * Application-scoped roles are deliberately excluded from this organization\n * administration reference.\n */\nexport function projectApplicationOrganizationRoleDocumentationSources(\n customRoles: Readonly<Record<string, ApplicationRoleConfigurationProjectionInput>> | undefined,\n roleSpecsByRef: ReadonlyMap<string, ApplicationRoleDocumentationSource>,\n): readonly ApplicationOrganizationRoleDocumentationSource[] {\n const configured = new Map<string, ApplicationRoleConfigurationProjectionInput & { readonly role: string }>();\n for (const config of Object.values(DEFAULT_ORGANIZATION_ROLES)) {\n if (typeof config.role !== 'string' || config.role.length === 0) {\n throw new Error('application organization-role projector: framework organization role configuration has no role token');\n }\n configured.set(config.role, { ...config, role: config.role });\n }\n for (const config of Object.values(customRoles ?? {})) {\n if (typeof config.role !== 'string' || config.role.length === 0) {\n throw new Error('application organization-role projector: application organization role configuration has no role token');\n }\n if (configured.has(config.role)) {\n throw new Error(`application organization-role projector: application role '${config.role}' collides with a framework organization role`);\n }\n configured.set(config.role, { ...config, role: config.role });\n }\n\n return Object.freeze([...configured.values()]\n .filter((config) => config.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS)\n .map((config) => {\n const specification = roleSpecsByRef.get(config.role);\n if (\n specification === undefined\n || specification.purpose === null\n || specification.authorityBoundary === null\n || specification.useWhen === null\n || specification.avoidWhen === null\n || specification.businessConstraints === null\n ) {\n throw new Error(\n `application organization-role projector: organization role '${config.role}' has no companion-exported role specification with complete consumer guidance`,\n );\n }\n return Object.freeze({\n role: config.role,\n inheritFrom: config.inheritFrom ?? null,\n purpose: specification.purpose,\n businessRole: specification.businessRole,\n authorityBoundary: specification.authorityBoundary,\n useWhen: specification.useWhen,\n avoidWhen: specification.avoidWhen,\n businessConstraints: specification.businessConstraints,\n });\n })\n .sort((left, right) => left.role.localeCompare(right.role, 'en-US')));\n}\n\n/**\n * Join role semantics to the exact primary-locale labels shown by the\n * application. Missing values fail closed: publishing a guessed label would\n * make the guide disagree with member-management and role-picker UI.\n */\nexport function resolveApplicationOrganizationRoleDocumentation(\n roles: readonly ApplicationOrganizationRoleDocumentationSource[],\n primaryLocaleLabels: Readonly<Record<string, string>>,\n): readonly ApplicationOrganizationRoleDocumentation[] {\n return Object.freeze(roles.map((role) => Object.freeze({\n ...role,\n label: requiredRoleLabel(primaryLocaleLabels, role.role, 'label'),\n description: requiredRoleLabel(primaryLocaleLabels, role.role, 'description'),\n })));\n}\n\n/**\n * Give every operation's access documentation the role names the APPLICATION authored.\n *\n * ## The defect this closes\n *\n * `roleRequirements[].label` was derived from the role TOKEN in the projector subprocess —\n * `ORG_MANAGER` became \"Organization Manager\" and `APP_ADMIN_SUPER_ADMIN` became \"Application Admin\n * Super Admin\". That is invented display text (`.claude/rules/display-text-comes-from-i18n.md`), and\n * it appeared on EVERY documented operation, which is the largest surface the defect had. Meanwhile\n * the same roles carry authored labels resolved from the application's own i18n unit, and\n * publication already refuses to proceed without them — but those labels reached only the roles\n * page. Two names for one role, and the invented one was the one beside every endpoint (#382).\n *\n * ## Why a token is the fallback, and not a prettier guess\n *\n * A label this map does not carry stays the raw token. `ORG_MANAGER` is honest, searchable, and\n * visibly not a product's word — an invented English phrase is none of those, and once printed it is\n * indistinguishable from an authored one. The refusal belongs at the door that PUBLISHES, which\n * already has it; a read that merely generates a document must not fail closed on an authoring gap.\n *\n * Returns new objects; the input projections are left untouched.\n */\nexport function applyAuthoredRoleLabelsToOperationAccess<\n T extends { readonly access?: { readonly roleRequirements: readonly { readonly role: string; readonly label: string }[] } },\n>(operations: readonly T[], labelByRole: Readonly<Record<string, string>>): readonly T[] {\n return operations.map((operation) => {\n const access = operation.access;\n if (access === undefined || access.roleRequirements.length === 0) return operation;\n let changed = false;\n const roleRequirements = access.roleRequirements.map((requirement) => {\n const authored = labelByRole[requirement.role];\n if (authored === undefined || authored === requirement.label) return requirement;\n changed = true;\n return { ...requirement, label: authored };\n });\n return changed ? { ...operation, access: { ...access, roleRequirements } } : operation;\n });\n}\n\n/**\n * Materialize the reusable Markdown fact consumed by the Roles and permissions\n * topic. This function knows no application identity: different applications\n * receive different role inputs and therefore different facts.\n */\nexport function createApplicationOrganizationRolesDocumentationFact(\n roles: readonly ApplicationOrganizationRoleDocumentation[],\n): ApplicationOrganizationRolesDocumentationFact {\n if (roles.length === 0) throw new Error('technical documentation requires at least one resolved organization role');\n if (new Set(roles.map((role) => role.role)).size !== roles.length) {\n throw new Error('technical documentation received duplicate resolved organization roles');\n }\n\n const roleByIdentifier = new Map(roles.map((role) => [role.role, role]));\n const hierarchyDepthByRole = new Map(roles.map((role) => [role.role, hierarchyDepth(role, roleByIdentifier)]));\n // Readers compare authority from broadest to narrowest. Derive that order\n // from the actual inheritance chain; sibling branches use visible labels and\n // stable role tokens only as deterministic tie-breakers.\n const canonicalRoles = [...roles].sort((left, right) =>\n hierarchyDepthByRole.get(right.role)! - hierarchyDepthByRole.get(left.role)!\n || left.label.localeCompare(right.label, 'en-US')\n || left.role.localeCompare(right.role, 'en-US'));\n\n const roleSections = canonicalRoles.map((role) => {\n const inheritedRole = role.inheritFrom === null ? undefined : roleByIdentifier.get(role.inheritFrom);\n const inheritance = role.inheritFrom === null\n ? 'This role does not inherit another organization role.'\n : `This role includes the permissions of **${markdownText(inheritedRole?.label ?? role.inheritFrom)}** (${inlineCode(role.inheritFrom)}).`;\n const limits = [role.avoidWhen, ...role.businessConstraints]\n .map((constraint) => `- ${markdownProse(constraint)}`)\n .join('\\n');\n return `### ${markdownText(role.label)}\\n\\n${markdownText(role.description)}\\n\\n- **Where it applies:** ${markdownProse(role.authorityBoundary)}\\n- **Inherited access:** ${inheritance}\\n- **Technical identifier:** ${inlineCode(role.role)}\\n\\n#### Can do\\n\\n${markdownProse(role.purpose)}\\n\\n${markdownProse(role.useWhen)}\\n\\n#### Cannot do\\n\\n${limits}\\n\\n#### Can assign\\n\\n${roleAssignmentMarkdown(role, roleByIdentifier)}`;\n }).join('\\n\\n');\n\n return Object.freeze({\n sourceRef: APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_REF,\n markdown: `These are all the organization roles available in this application. Their names and short descriptions match the application's primary-language interface; the technical identifier is included so you can recognize the same role in an access request, audit record, or API response.\\n\\n${roleSections}\\n\\n> **How inherited access works:** when one role includes another, it receives the included role’s permissions as well as its own. The reverse is not true: assigning the included role never grants the higher role.`,\n sourceVersion: APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_VERSION,\n });\n}\n\nfunction hierarchyDepth(\n role: ApplicationOrganizationRoleDocumentation,\n roleByIdentifier: ReadonlyMap<string, ApplicationOrganizationRoleDocumentation>,\n ancestors = new Set<string>(),\n): number {\n if (role.inheritFrom === null) return 0;\n if (ancestors.has(role.role)) {\n throw new Error(`technical documentation organization-role hierarchy contains a cycle at ${role.role}`);\n }\n const inheritedRole = roleByIdentifier.get(role.inheritFrom);\n if (inheritedRole === undefined) {\n throw new Error(`technical documentation organization role ${role.role} inherits absent role ${role.inheritFrom}`);\n }\n return 1 + hierarchyDepth(inheritedRole, roleByIdentifier, new Set([...ancestors, role.role]));\n}\n\n/**\n * Explain the standard organization-role assignment ceiling from the exact\n * application role graph. This deliberately does not flatten custom roles into\n * a total order: sibling custom branches are outside one another's ceiling.\n * A role must also inherit the administrator gate before it can use the\n * standard membership and unit-assignment controls at all.\n */\nfunction roleAssignmentMarkdown(\n role: ApplicationOrganizationRoleDocumentation,\n roleByIdentifier: ReadonlyMap<string, ApplicationOrganizationRoleDocumentation>,\n): string {\n const effectiveRoles: ApplicationOrganizationRoleDocumentation[] = [];\n let current: ApplicationOrganizationRoleDocumentation | undefined = role;\n const visited = new Set<string>();\n while (current !== undefined) {\n if (visited.has(current.role)) {\n throw new Error(`technical documentation organization-role hierarchy contains a cycle at ${current.role}`);\n }\n visited.add(current.role);\n effectiveRoles.push(current);\n current = current.inheritFrom === null ? undefined : roleByIdentifier.get(current.inheritFrom);\n }\n\n if (!effectiveRoles.some((candidate) => candidate.role === CORE_ORG_ROLES.ORG_ADMIN)) {\n return 'This role cannot use the standard organization-membership or organization-unit assignment controls. It therefore cannot assign an organization or unit role through those controls.';\n }\n\n const assignableRoles = effectiveRoles\n .map((candidate) => `**${markdownText(candidate.label)}** (${inlineCode(candidate.role)})`)\n .join(', ');\n return `Through the standard membership and unit-assignment controls, this role can assign: ${assignableRoles}. It cannot assign a role outside this inheritance chain unless the person also holds another organization-wide role whose chain includes it.`;\n}\n\nfunction requiredRoleLabel(\n labels: Readonly<Record<string, string>>,\n role: string,\n field: 'label' | 'description',\n): string {\n const key = `roles.${role}.${field}`;\n const value = labels[key];\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(\n `application organization-role documentation requires primary-locale label '${key}'; generate the application's role labels before publishing documentation`,\n );\n }\n return value.trim();\n}\n\nfunction nonEmptyStringOrNull(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;\n}\n\nfunction nonEmptyStringArrayOrNull(value: unknown): readonly string[] | null {\n if (!Array.isArray(value) || value.length === 0) return null;\n const normalized = value.map(nonEmptyStringOrNull);\n return normalized.every((entry): entry is string => entry !== null)\n ? Object.freeze(normalized)\n : null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction markdownText(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim().replaceAll('\\\\', '\\\\\\\\').replaceAll(/([`*_[\\]<>#|])/g, '\\\\$1');\n}\n\n/** Role specifications intentionally author small inline-Markdown semantics. */\nfunction markdownProse(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim();\n}\n\nfunction inlineCode(value: string): string {\n return `\\`${value.replaceAll('`', '`')}\\``;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"application-organization-role-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-organization-role-documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,CAAC,MAAM,uDAAuD,GAAG,gDAAyD,CAAC;AACjI,4GAA4G;AAC5G,MAAM,CAAC,MAAM,2DAA2D,GAAG,CAAC,CAAC;AAyC7E;;;GAGG;AACH,MAAM,UAAU,wCAAwC,CACtD,kBAAuD;IAEvD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8C,CAAC;IACrE,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC3G,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,8EAA8E,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;QAClH,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACxB,GAAG,EAAE,SAAS,CAAC,GAAG;YAClB,OAAO,EAAE,oBAAoB,CAAC,SAAS,CAAC,OAAO,CAAC;YAChD,YAAY,EAAE,oBAAoB,CAAC,SAAS,CAAC,YAAY,CAAC;YAC1D,iBAAiB,EAAE,oBAAoB,CAAC,SAAS,CAAC,iBAAiB,CAAC;YACpE,OAAO,EAAE,oBAAoB,CAAC,SAAS,CAAC,OAAO,CAAC;YAChD,SAAS,EAAE,oBAAoB,CAAC,SAAS,CAAC,SAAS,CAAC;YACpD,mBAAmB,EAAE,yBAAyB,CAAC,SAAS,CAAC,mBAAmB,CAAC;SAC9E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sDAAsD,CACpE,WAA8F,EAC9F,cAAuE;IAEvE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmF,CAAC;IAC9G,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,0BAA0B,CAAC,EAAE,CAAC;QAC/D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,sGAAsG,CAAC,CAAC;QAC1H,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;QACtD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,wGAAwG,CAAC,CAAC;QAC5H,CAAC;QACD,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,8DAA8D,MAAM,CAAC,IAAI,+CAA+C,CAAC,CAAC;QAC5I,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;SAC1C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,KAAK,oBAAoB,CAAC,aAAa,CAAC;SACrF,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IACE,aAAa,KAAK,SAAS;eACxB,aAAa,CAAC,OAAO,KAAK,IAAI;eAC9B,aAAa,CAAC,iBAAiB,KAAK,IAAI;eACxC,aAAa,CAAC,OAAO,KAAK,IAAI;eAC9B,aAAa,CAAC,SAAS,KAAK,IAAI;eAChC,aAAa,CAAC,mBAAmB,KAAK,IAAI,EAC7C,CAAC;YACD,MAAM,IAAI,KAAK,CACb,+DAA+D,MAAM,CAAC,IAAI,gFAAgF,CAC3J,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;YACvC,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,YAAY,EAAE,aAAa,CAAC,YAAY;YACxC,iBAAiB,EAAE,aAAa,CAAC,iBAAiB;YAClD,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,SAAS,EAAE,aAAa,CAAC,SAAS;YAClC,mBAAmB,EAAE,aAAa,CAAC,mBAAmB;SACvD,CAAC,CAAC;IACL,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+CAA+C,CAC7D,KAAgE,EAChE,mBAAqD;IAErD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;QACrD,GAAG,IAAI;QACP,KAAK,EAAE,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;QACjE,WAAW,EAAE,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;KAC9E,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,wCAAwC,CAEtD,UAAwB,EAAE,WAA6C;IACvE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAChC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACnF,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;YACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,WAAW,CAAC,KAAK;gBAAE,OAAO,WAAW,CAAC;YACjF,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACzF,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mDAAmD,CACjE,KAA0D;IAE1D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IACpH,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/G,0EAA0E;IAC1E,6EAA6E;IAC7E,yDAAyD;IACzD,MAAM,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACrD,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,GAAG,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAE;WACzE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;WAC9C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrG,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI;YAC3C,CAAC,CAAC,uDAAuD;YACzD,CAAC,CAAC,2CAA2C,YAAY,CAAC,aAAa,EAAE,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAC7I,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC;aACzD,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;aACrD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,+BAA+B,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,6BAA6B,WAAW,iCAAiC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,MAAM,0BAA0B,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,CAAC;IAC5a,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,uDAAuD;QAClE,QAAQ,EAAE,8RAA8R,YAAY,0NAA0N;QAC9gB,aAAa,EAAE,2DAA2D;KAC3E,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CACrB,IAA8C,EAC9C,gBAA+E,EAC/E,YAAY,IAAI,GAAG,EAAU;IAE7B,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IACxC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,2EAA2E,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC;IACD,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7D,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,CAAC,IAAI,yBAAyB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,CAAC,GAAG,cAAc,CAAC,aAAa,EAAE,gBAAgB,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAC7B,IAA8C,EAC9C,gBAA+E;IAE/E,MAAM,cAAc,GAA+C,EAAE,CAAC;IACtE,IAAI,OAAO,GAAyD,IAAI,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,OAAO,OAAO,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,2EAA2E,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7G,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,GAAG,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;QACrF,OAAO,qLAAqL,CAAC;IAC/L,CAAC;IAED,MAAM,eAAe,GAAG,cAAc;SACnC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;SAC1F,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,uFAAuF,eAAe,+IAA+I,CAAC;AAC/P,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAwC,EACxC,IAAY,EACZ,KAA8B;IAE9B,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,KAAK,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,8EAA8E,GAAG,2EAA2E,CAC7J,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAc;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;QACjE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;QAC3B,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAC7G,CAAC;AAED,gFAAgF;AAChF,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC;AACjD,CAAC","sourcesContent":["import {\n CORE_ORG_ROLES,\n DEFAULT_ORGANIZATION_ROLES,\n ResourcePrimaryScope,\n} from '@wildo-ai/saas-models';\nimport {\n} from '@wildo-ai/saas-specifications/technical-documentation';\n\nimport type { ApplicationOrganizationRolesDocumentationFact } from './technical-documentation-engine-content-bundle';\n\nexport const APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:organization-roles' as const;\n/** Advances when this projection's shape changes; it is the fact's version wherever provenance cites it. */\nexport const APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_VERSION = 1;\n\n/** Minimal application/engine role specification needed by consumer documentation. */\nexport interface ApplicationRoleDocumentationSource {\n readonly ref: string;\n readonly purpose: string | null;\n readonly businessRole: string | null;\n readonly authorityBoundary: string | null;\n readonly useWhen: string | null;\n readonly avoidWhen: string | null;\n readonly businessConstraints: readonly string[] | null;\n}\n\n/**\n * Application-independent organization-role projection before UI labels are\n * joined. The introspection subprocess can safely emit this JSON-only shape;\n * the parent companion later joins the application's primary-locale labels.\n */\nexport interface ApplicationOrganizationRoleDocumentationSource {\n readonly role: string;\n readonly inheritFrom: string | null;\n readonly purpose: string;\n readonly businessRole: string | null;\n readonly authorityBoundary: string;\n readonly useWhen: string;\n readonly avoidWhen: string;\n readonly businessConstraints: readonly string[];\n}\n\n/** Complete consumer-visible role documentation after the application label join. */\nexport interface ApplicationOrganizationRoleDocumentation extends ApplicationOrganizationRoleDocumentationSource {\n readonly label: string;\n readonly description: string;\n}\n\ninterface ApplicationRoleConfigurationProjectionInput {\n readonly role?: string;\n readonly inheritFrom?: string;\n readonly relatedPrimaryScope: ResourcePrimaryScope;\n}\n\n/**\n * Index companion-exported role specifications by their runtime role token.\n * Engine and application-defined roles intentionally share this namespace.\n */\nexport function indexApplicationRoleDocumentationSources(\n roleSpecifications: Record<string, unknown> | undefined,\n): ReadonlyMap<string, ApplicationRoleDocumentationSource> {\n const result = new Map<string, ApplicationRoleDocumentationSource>();\n for (const candidate of Object.values(roleSpecifications ?? {})) {\n if (!isPlainObject(candidate) || typeof candidate.ref !== 'string' || candidate.ref.length === 0) continue;\n if (result.has(candidate.ref)) {\n throw new Error(`application organization-role projector: duplicate role specification for '${candidate.ref}'`);\n }\n result.set(candidate.ref, {\n ref: candidate.ref,\n purpose: nonEmptyStringOrNull(candidate.purpose),\n businessRole: nonEmptyStringOrNull(candidate.businessRole),\n authorityBoundary: nonEmptyStringOrNull(candidate.authorityBoundary),\n useWhen: nonEmptyStringOrNull(candidate.useWhen),\n avoidWhen: nonEmptyStringOrNull(candidate.avoidWhen),\n businessConstraints: nonEmptyStringArrayOrNull(candidate.businessConstraints),\n });\n }\n return result;\n}\n\n/**\n * Resolve every framework and application-defined organization role from the\n * application's merged runtime registry and authored role specifications.\n * Application-scoped roles are deliberately excluded from this organization\n * administration reference.\n */\nexport function projectApplicationOrganizationRoleDocumentationSources(\n customRoles: Readonly<Record<string, ApplicationRoleConfigurationProjectionInput>> | undefined,\n roleSpecsByRef: ReadonlyMap<string, ApplicationRoleDocumentationSource>,\n): readonly ApplicationOrganizationRoleDocumentationSource[] {\n const configured = new Map<string, ApplicationRoleConfigurationProjectionInput & { readonly role: string }>();\n for (const config of Object.values(DEFAULT_ORGANIZATION_ROLES)) {\n if (typeof config.role !== 'string' || config.role.length === 0) {\n throw new Error('application organization-role projector: framework organization role configuration has no role token');\n }\n configured.set(config.role, { ...config, role: config.role });\n }\n for (const config of Object.values(customRoles ?? {})) {\n if (typeof config.role !== 'string' || config.role.length === 0) {\n throw new Error('application organization-role projector: application organization role configuration has no role token');\n }\n if (configured.has(config.role)) {\n throw new Error(`application organization-role projector: application role '${config.role}' collides with a framework organization role`);\n }\n configured.set(config.role, { ...config, role: config.role });\n }\n\n return Object.freeze([...configured.values()]\n .filter((config) => config.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS)\n .map((config) => {\n const specification = roleSpecsByRef.get(config.role);\n if (\n specification === undefined\n || specification.purpose === null\n || specification.authorityBoundary === null\n || specification.useWhen === null\n || specification.avoidWhen === null\n || specification.businessConstraints === null\n ) {\n throw new Error(\n `application organization-role projector: organization role '${config.role}' has no companion-exported role specification with complete consumer guidance`,\n );\n }\n return Object.freeze({\n role: config.role,\n inheritFrom: config.inheritFrom ?? null,\n purpose: specification.purpose,\n businessRole: specification.businessRole,\n authorityBoundary: specification.authorityBoundary,\n useWhen: specification.useWhen,\n avoidWhen: specification.avoidWhen,\n businessConstraints: specification.businessConstraints,\n });\n })\n .sort((left, right) => left.role.localeCompare(right.role, 'en-US')));\n}\n\n/**\n * Join role semantics to the exact primary-locale labels shown by the\n * application. Missing values fail closed: publishing a guessed label would\n * make the guide disagree with member-management and role-picker UI.\n */\nexport function resolveApplicationOrganizationRoleDocumentation(\n roles: readonly ApplicationOrganizationRoleDocumentationSource[],\n primaryLocaleLabels: Readonly<Record<string, string>>,\n): readonly ApplicationOrganizationRoleDocumentation[] {\n return Object.freeze(roles.map((role) => Object.freeze({\n ...role,\n label: requiredRoleLabel(primaryLocaleLabels, role.role, 'label'),\n description: requiredRoleLabel(primaryLocaleLabels, role.role, 'description'),\n })));\n}\n\n/**\n * Give every operation's access documentation the role names the APPLICATION authored.\n *\n * ## The defect this closes\n *\n * `roleRequirements[].label` was derived from the role TOKEN in the projector subprocess —\n * `ORG_MANAGER` became \"Organization Manager\" and `APP_ADMIN_SUPER_ADMIN` became \"Application Admin\n * Super Admin\". That is invented display text (`.claude/rules/display-text-comes-from-i18n.md`), and\n * it appeared on EVERY documented operation, which is the largest surface the defect had. Meanwhile\n * the same roles carry authored labels resolved from the application's own i18n unit, and\n * publication already refuses to proceed without them — but those labels reached only the roles\n * page. Two names for one role, and the invented one was the one beside every endpoint (#382).\n *\n * ## Why a token is the fallback, and not a prettier guess\n *\n * A label this map does not carry stays the raw token. `ORG_MANAGER` is honest, searchable, and\n * visibly not a product's word — an invented English phrase is none of those, and once printed it is\n * indistinguishable from an authored one. The refusal belongs at the door that PUBLISHES, which\n * already has it; a read that merely generates a document must not fail closed on an authoring gap.\n *\n * Returns new objects; the input projections are left untouched.\n */\nexport function applyAuthoredRoleLabelsToOperationAccess<\n T extends { readonly access?: { readonly roleRequirements: readonly { readonly role: string; readonly label: string }[] } },\n>(operations: readonly T[], labelByRole: Readonly<Record<string, string>>): readonly T[] {\n return operations.map((operation) => {\n const access = operation.access;\n if (access === undefined || access.roleRequirements.length === 0) return operation;\n let changed = false;\n const roleRequirements = access.roleRequirements.map((requirement) => {\n const authored = labelByRole[requirement.role];\n if (authored === undefined || authored === requirement.label) return requirement;\n changed = true;\n return { ...requirement, label: authored };\n });\n return changed ? { ...operation, access: { ...access, roleRequirements } } : operation;\n });\n}\n\n/**\n * Materialize the reusable Markdown fact consumed by the Roles and permissions\n * topic. This function knows no application identity: different applications\n * receive different role inputs and therefore different facts.\n */\nexport function createApplicationOrganizationRolesDocumentationFact(\n roles: readonly ApplicationOrganizationRoleDocumentation[],\n): ApplicationOrganizationRolesDocumentationFact {\n if (roles.length === 0) throw new Error('technical documentation requires at least one resolved organization role');\n if (new Set(roles.map((role) => role.role)).size !== roles.length) {\n throw new Error('technical documentation received duplicate resolved organization roles');\n }\n\n const roleByIdentifier = new Map(roles.map((role) => [role.role, role]));\n const hierarchyDepthByRole = new Map(roles.map((role) => [role.role, hierarchyDepth(role, roleByIdentifier)]));\n // Readers compare authority from broadest to narrowest. Derive that order\n // from the actual inheritance chain; sibling branches use visible labels and\n // stable role tokens only as deterministic tie-breakers.\n const canonicalRoles = [...roles].sort((left, right) =>\n hierarchyDepthByRole.get(right.role)! - hierarchyDepthByRole.get(left.role)!\n || left.label.localeCompare(right.label, 'en-US')\n || left.role.localeCompare(right.role, 'en-US'));\n\n const roleSections = canonicalRoles.map((role) => {\n const inheritedRole = role.inheritFrom === null ? undefined : roleByIdentifier.get(role.inheritFrom);\n const inheritance = role.inheritFrom === null\n ? 'This role does not inherit another organization role.'\n : `This role includes the permissions of **${markdownText(inheritedRole?.label ?? role.inheritFrom)}** (${inlineCode(role.inheritFrom)}).`;\n const limits = [role.avoidWhen, ...role.businessConstraints]\n .map((constraint) => `- ${markdownProse(constraint)}`)\n .join('\\n');\n return `### ${markdownText(role.label)}\\n\\n${markdownText(role.description)}\\n\\n- **Where it applies:** ${markdownProse(role.authorityBoundary)}\\n- **Inherited access:** ${inheritance}\\n- **Technical identifier:** ${inlineCode(role.role)}\\n\\n#### Can do\\n\\n${markdownProse(role.purpose)}\\n\\n${markdownProse(role.useWhen)}\\n\\n#### Cannot do\\n\\n${limits}\\n\\n#### Can assign\\n\\n${roleAssignmentMarkdown(role, roleByIdentifier)}`;\n }).join('\\n\\n');\n\n return Object.freeze({\n sourceRef: APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_REF,\n markdown: `These are all the organization roles available in this application. Their names and short descriptions match the application's primary-language interface; the technical identifier is included so you can recognize the same role in an access request, audit record, or API response.\\n\\n${roleSections}\\n\\n> **How inherited access works:** when one role includes another, it receives the included role’s permissions as well as its own. The reverse is not true: assigning the included role never grants the higher role.`,\n sourceVersion: APPLICATION_ORGANIZATION_ROLES_DOCUMENTATION_SOURCE_VERSION,\n });\n}\n\nfunction hierarchyDepth(\n role: ApplicationOrganizationRoleDocumentation,\n roleByIdentifier: ReadonlyMap<string, ApplicationOrganizationRoleDocumentation>,\n ancestors = new Set<string>(),\n): number {\n if (role.inheritFrom === null) return 0;\n if (ancestors.has(role.role)) {\n throw new Error(`technical documentation organization-role hierarchy contains a cycle at ${role.role}`);\n }\n const inheritedRole = roleByIdentifier.get(role.inheritFrom);\n if (inheritedRole === undefined) {\n throw new Error(`technical documentation organization role ${role.role} inherits absent role ${role.inheritFrom}`);\n }\n return 1 + hierarchyDepth(inheritedRole, roleByIdentifier, new Set([...ancestors, role.role]));\n}\n\n/**\n * Explain the standard organization-role assignment ceiling from the exact\n * application role graph. This deliberately does not flatten custom roles into\n * a total order: sibling custom branches are outside one another's ceiling.\n * A role must also inherit the administrator gate before it can use the\n * standard membership and unit-assignment controls at all.\n */\nfunction roleAssignmentMarkdown(\n role: ApplicationOrganizationRoleDocumentation,\n roleByIdentifier: ReadonlyMap<string, ApplicationOrganizationRoleDocumentation>,\n): string {\n const effectiveRoles: ApplicationOrganizationRoleDocumentation[] = [];\n let current: ApplicationOrganizationRoleDocumentation | undefined = role;\n const visited = new Set<string>();\n while (current !== undefined) {\n if (visited.has(current.role)) {\n throw new Error(`technical documentation organization-role hierarchy contains a cycle at ${current.role}`);\n }\n visited.add(current.role);\n effectiveRoles.push(current);\n current = current.inheritFrom === null ? undefined : roleByIdentifier.get(current.inheritFrom);\n }\n\n if (!effectiveRoles.some((candidate) => candidate.role === CORE_ORG_ROLES.ORG_ADMIN)) {\n return 'This role cannot use the standard organization-membership or organization-unit assignment controls. It therefore cannot assign an organization or unit role through those controls.';\n }\n\n const assignableRoles = effectiveRoles\n .map((candidate) => `**${markdownText(candidate.label)}** (${inlineCode(candidate.role)})`)\n .join(', ');\n return `Through the standard membership and unit-assignment controls, this role can assign: ${assignableRoles}. It cannot assign a role outside this inheritance chain unless the person also holds another organization-wide role whose chain includes it.`;\n}\n\nfunction requiredRoleLabel(\n labels: Readonly<Record<string, string>>,\n role: string,\n field: 'label' | 'description',\n): string {\n const key = `roles.${role}.${field}`;\n const value = labels[key];\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(\n `application organization-role documentation requires primary-locale label '${key}'; generate the application's role labels before publishing documentation`,\n );\n }\n return value.trim();\n}\n\nfunction nonEmptyStringOrNull(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;\n}\n\nfunction nonEmptyStringArrayOrNull(value: unknown): readonly string[] | null {\n if (!Array.isArray(value) || value.length === 0) return null;\n const normalized = value.map(nonEmptyStringOrNull);\n return normalized.every((entry): entry is string => entry !== null)\n ? Object.freeze(normalized)\n : null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction markdownText(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim().replaceAll('\\\\', '\\\\\\\\').replaceAll(/([`*_[\\]<>#|])/g, '\\\\$1');\n}\n\n/** Role specifications intentionally author small inline-Markdown semantics. */\nfunction markdownProse(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim();\n}\n\nfunction inlineCode(value: string): string {\n return `\\`${value.replaceAll('`', '`')}\\``;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-organization-unit-resource-documentation.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-organization-unit-resource-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-organization-unit-resource-documentation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,eAAO,MAAM,gEAAgE,EAC3E,+DAAwE,CAAC;AAC3E,4GAA4G;AAC5G,eAAO,MAAM,oEAAoE,IAAI,CAAC;AAEtF,0EAA0E;AAC1E,MAAM,WAAW,qDAAqD;IACpE,QAAQ,CAAC,SAAS,EAAE,OAAO,gEAAgE,CAAC;IAC5F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,gDAAgD;IAC/D,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,uDAAuD,CACrE,yBAAyB,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC,GAAG,SAAS,EAC5G,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,SAAS,gDAAgD,EAAE,CA4B7D;AAED,kFAAkF;AAClF,wBAAgB,2DAA2D,CACzE,SAAS,EAAE,SAAS,gDAAgD,EAAE,GACrE,qDAAqD,CAiBvD"}
|
|
@@ -55,7 +55,10 @@ export function createApplicationOrganizationUnitResourcesDocumentationFact(reso
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
/** Match the native API-reference fallback without changing resource identity. */
|
|
58
|
+
// Generated API-reference prose, as in `openapi-reference-model.ts`. The technical-doc lane has no
|
|
59
|
+
// label tree and is not translated.
|
|
58
60
|
function resourceDisplayLabel(identifier) {
|
|
61
|
+
// invented-display-text: generated API-reference prose.
|
|
59
62
|
return identifier
|
|
60
63
|
.replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
61
64
|
.replaceAll(/[-_]+/g, ' ')
|
|
@@ -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":"AAKA,MAAM,CAAC,MAAM,gEAAgE,GAC3E,+DAAwE,CAAC;AAC3E,4GAA4G;AAC5G,MAAM,CAAC,MAAM,oEAAoE,GAAG,CAAC,CAAC;AAqBtF;;;;;;;;GAQG;AACH,MAAM,UAAU,uDAAuD,CACrE,yBAA4G,EAC5G,YAAoC;IAEpC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACxD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,6EAA6E,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QAC5G,CAAC;QACD,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,yBAAyB,IAAI,EAAE,CAAC;SACjE,MAAM,CAAC,CAAC,KAAK,EAAyD,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SAChG,GAAG,CAAC,CAAC,CAAC,kBAAkB,EAAE,WAAW,CAAC,EAAE,EAAE;QACzC,IAAI,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,sDAAsD,kBAAkB,4CAA4C,CAAC,CAAC;QACxI,CAAC;QACD,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACrD,IAAI,GAAG,EAAE,WAAW,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,wEAAwE,kBAAkB,sCAAsC,CACjI,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,kBAAkB;YAClB,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC;YAC/C,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;SAChC,CAAC,CAAC;IACL,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACxJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,2DAA2D,CACzE,SAAsE;IAEtE,IAAI,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAChG,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,kBAAkB,GAAG,CAAC,GAAG,SAAS,CAAC;SACtC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,CAAC;IACrJ,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,KAAK,CAAC;QAC9C,CAAC,CAAC,4MAA4M;QAC9M,CAAC,CAAC,sEAAsE,kBAAkB;aACvF,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;aAC9F,IAAI,CAAC,IAAI,CAAC,mJAAmJ,CAAC;IAEnK,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,gEAAgE;QAC3E,QAAQ;QACR,aAAa,EAAE,oEAAoE;KACpF,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAClF,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,OAAO,UAAU;SACd,UAAU,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACzC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC;SACzB,IAAI,EAAE;SACN,KAAK,CAAC,MAAM,CAAC;SACb,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;SACnH,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAC7G,CAAC","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"]}
|