@wildo-ai/saas-technical-doc 1.1.2 → 1.1.4
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 +25 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.js +28 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -1
- package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts +133 -0
- package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts.map +1 -0
- package/dist/esm/companion/application-documentation/application-domain-documentation.js +243 -0
- package/dist/esm/companion/application-documentation/application-domain-documentation.js.map +1 -0
- package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-integration-documentation.js +23 -0
- 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 +30 -0
- 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 +38 -0
- 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/technical-documentation-engine-content-bundle.d.ts +61 -1
- 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 +255 -218
- 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 +2 -0
- 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 +1 -0
- 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 +1 -1
- 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 -1
- package/dist/esm/companion/index.d.ts.map +1 -1
- package/dist/esm/companion/index.js +2 -1
- package/dist/esm/companion/index.js.map +1 -1
- package/dist/esm/companion/manual-controller-route-projection.d.ts +112 -0
- package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -0
- package/dist/esm/companion/manual-controller-route-projection.js +249 -0
- package/dist/esm/companion/manual-controller-route-projection.js.map +1 -0
- package/dist/esm/companion/openapi-generator.d.ts +16 -0
- package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
- package/dist/esm/companion/openapi-generator.js +493 -26
- package/dist/esm/companion/openapi-generator.js.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.d.ts +44 -0
- package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.js +37 -0
- package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
- package/dist/esm/companion/publish-result.types.d.ts +37 -4
- 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 +7 -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 +34 -18
- 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 +8 -1
- 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.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 +30 -13
- 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 +10 -0
- 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 +10 -15
- package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.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 +27 -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 +33 -0
- package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -0
- package/dist/esm/companion/technical-documentation-diagram-definitions.js +54 -0
- package/dist/esm/companion/technical-documentation-diagram-definitions.js.map +1 -0
- package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts +10 -18
- package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-materializer.js +9 -39
- 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 +8 -4
- package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
- package/dist/esm/config/wildo-tech-doc-config.schemas.js +8 -4
- 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 +42 -64
- package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content.techdoc.js +164 -925
- 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.map +1 -1
- package/dist/esm/openapi/index.d.ts.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.map +1 -1
- package/dist/esm/runtime/AuthExchangePage.d.ts.map +1 -1
- package/dist/esm/runtime/DocsAuthContext.d.ts +16 -1
- package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
- package/dist/esm/runtime/DocsAuthContext.js +18 -2
- package/dist/esm/runtime/DocsAuthContext.js.map +1 -1
- 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/frontend-provider-registry.techdoc.d.ts +35 -13
- package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
- package/dist/esm/runtime/frontend-provider-registry.techdoc.js +28 -19
- package/dist/esm/runtime/frontend-provider-registry.techdoc.js.map +1 -1
- package/dist/esm/runtime/index.d.ts +1 -0
- package/dist/esm/runtime/index.d.ts.map +1 -1
- package/dist/esm/runtime/index.js +1 -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/use-docs-auth-session.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-provider-sdks.d.ts +21 -0
- package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -0
- package/dist/esm/runtime/use-docs-provider-sdks.js +49 -0
- package/dist/esm/runtime/use-docs-provider-sdks.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts +0 -9
- package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts.map +0 -1
- package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js +0 -111
- package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js.map +0 -1
|
@@ -0,0 +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"]}
|
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
CHANGED
|
@@ -43,13 +43,36 @@ function webhookEventsMarkdown(source) {
|
|
|
43
43
|
* application produce identical bytes.
|
|
44
44
|
*/
|
|
45
45
|
export function projectApplicationIntegrationDocumentation(source) {
|
|
46
|
+
/*
|
|
47
|
+
* Both inventories are ADDRESSES: a tool name is what an agent types, and a (resource, operation,
|
|
48
|
+
* channel) triple is one fact about one delivery. Neither can legitimately appear twice, so a
|
|
49
|
+
* repeat is a producer walking something twice — which is exactly what the companion's collector
|
|
50
|
+
* did, visiting every selected core resource once from the prepared list and once from the core
|
|
51
|
+
* factory sweep. It survived because the collector used to answer a boolean, where duplicates are
|
|
52
|
+
* unobservable.
|
|
53
|
+
*
|
|
54
|
+
* The refusal lives HERE rather than only in that collector because this is the one place every
|
|
55
|
+
* producer passes through, and a duplicated row is worse than a loud failure: it reads as two
|
|
56
|
+
* separate things a reader must tell apart.
|
|
57
|
+
*/
|
|
58
|
+
const seenToolNames = new Set();
|
|
46
59
|
for (const tool of source.mcpTools) {
|
|
47
60
|
if (tool.toolName.trim().length === 0)
|
|
48
61
|
throw new Error('application integration projection received an MCP tool with no name');
|
|
62
|
+
if (seenToolNames.has(tool.toolName)) {
|
|
63
|
+
throw new Error(`application integration projection received the MCP tool '${tool.toolName}' twice — a tool name addresses one operation`);
|
|
64
|
+
}
|
|
65
|
+
seenToolNames.add(tool.toolName);
|
|
49
66
|
}
|
|
67
|
+
const seenEvents = new Set();
|
|
50
68
|
for (const event of source.webhookEvents) {
|
|
51
69
|
if (event.channel.trim().length === 0)
|
|
52
70
|
throw new Error('application integration projection received a webhook event with no channel');
|
|
71
|
+
const identity = `${event.resourceIdentifier}.${event.operationIdentifier}.${event.channel}`;
|
|
72
|
+
if (seenEvents.has(identity)) {
|
|
73
|
+
throw new Error(`application integration projection received the webhook event '${identity}' twice — one operation on one channel is one event`);
|
|
74
|
+
}
|
|
75
|
+
seenEvents.add(identity);
|
|
53
76
|
}
|
|
54
77
|
return {
|
|
55
78
|
sourceRef: APPLICATION_INTEGRATION_DOCUMENTATION_SOURCE_REF,
|
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"]}
|
|
@@ -56,6 +56,36 @@ export declare function projectApplicationOrganizationRoleDocumentationSources(c
|
|
|
56
56
|
* make the guide disagree with member-management and role-picker UI.
|
|
57
57
|
*/
|
|
58
58
|
export declare function resolveApplicationOrganizationRoleDocumentation(roles: readonly ApplicationOrganizationRoleDocumentationSource[], primaryLocaleLabels: Readonly<Record<string, string>>): readonly ApplicationOrganizationRoleDocumentation[];
|
|
59
|
+
/**
|
|
60
|
+
* Give every operation's access documentation the role names the APPLICATION authored.
|
|
61
|
+
*
|
|
62
|
+
* ## The defect this closes
|
|
63
|
+
*
|
|
64
|
+
* `roleRequirements[].label` was derived from the role TOKEN in the projector subprocess —
|
|
65
|
+
* `ORG_MANAGER` became "Organization Manager" and `APP_ADMIN_SUPER_ADMIN` became "Application Admin
|
|
66
|
+
* Super Admin". That is invented display text (`.claude/rules/display-text-comes-from-i18n.md`), and
|
|
67
|
+
* it appeared on EVERY documented operation, which is the largest surface the defect had. Meanwhile
|
|
68
|
+
* the same roles carry authored labels resolved from the application's own i18n unit, and
|
|
69
|
+
* publication already refuses to proceed without them — but those labels reached only the roles
|
|
70
|
+
* page. Two names for one role, and the invented one was the one beside every endpoint (#382).
|
|
71
|
+
*
|
|
72
|
+
* ## Why a token is the fallback, and not a prettier guess
|
|
73
|
+
*
|
|
74
|
+
* A label this map does not carry stays the raw token. `ORG_MANAGER` is honest, searchable, and
|
|
75
|
+
* visibly not a product's word — an invented English phrase is none of those, and once printed it is
|
|
76
|
+
* indistinguishable from an authored one. The refusal belongs at the door that PUBLISHES, which
|
|
77
|
+
* already has it; a read that merely generates a document must not fail closed on an authoring gap.
|
|
78
|
+
*
|
|
79
|
+
* Returns new objects; the input projections are left untouched.
|
|
80
|
+
*/
|
|
81
|
+
export declare function applyAuthoredRoleLabelsToOperationAccess<T extends {
|
|
82
|
+
readonly access?: {
|
|
83
|
+
readonly roleRequirements: readonly {
|
|
84
|
+
readonly role: string;
|
|
85
|
+
readonly label: string;
|
|
86
|
+
}[];
|
|
87
|
+
};
|
|
88
|
+
}>(operations: readonly T[], labelByRole: Readonly<Record<string, string>>): readonly T[];
|
|
59
89
|
/**
|
|
60
90
|
* Materialize the reusable Markdown fact consumed by the Roles and permissions
|
|
61
91
|
* topic. This function knows no application identity: different applications
|
|
@@ -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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"}
|
package/dist/esm/companion/application-documentation/application-organization-role-documentation.js
CHANGED
|
@@ -86,6 +86,44 @@ export function resolveApplicationOrganizationRoleDocumentation(roles, primaryLo
|
|
|
86
86
|
description: requiredRoleLabel(primaryLocaleLabels, role.role, 'description'),
|
|
87
87
|
})));
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Give every operation's access documentation the role names the APPLICATION authored.
|
|
91
|
+
*
|
|
92
|
+
* ## The defect this closes
|
|
93
|
+
*
|
|
94
|
+
* `roleRequirements[].label` was derived from the role TOKEN in the projector subprocess —
|
|
95
|
+
* `ORG_MANAGER` became "Organization Manager" and `APP_ADMIN_SUPER_ADMIN` became "Application Admin
|
|
96
|
+
* Super Admin". That is invented display text (`.claude/rules/display-text-comes-from-i18n.md`), and
|
|
97
|
+
* it appeared on EVERY documented operation, which is the largest surface the defect had. Meanwhile
|
|
98
|
+
* the same roles carry authored labels resolved from the application's own i18n unit, and
|
|
99
|
+
* publication already refuses to proceed without them — but those labels reached only the roles
|
|
100
|
+
* page. Two names for one role, and the invented one was the one beside every endpoint (#382).
|
|
101
|
+
*
|
|
102
|
+
* ## Why a token is the fallback, and not a prettier guess
|
|
103
|
+
*
|
|
104
|
+
* A label this map does not carry stays the raw token. `ORG_MANAGER` is honest, searchable, and
|
|
105
|
+
* visibly not a product's word — an invented English phrase is none of those, and once printed it is
|
|
106
|
+
* indistinguishable from an authored one. The refusal belongs at the door that PUBLISHES, which
|
|
107
|
+
* already has it; a read that merely generates a document must not fail closed on an authoring gap.
|
|
108
|
+
*
|
|
109
|
+
* Returns new objects; the input projections are left untouched.
|
|
110
|
+
*/
|
|
111
|
+
export function applyAuthoredRoleLabelsToOperationAccess(operations, labelByRole) {
|
|
112
|
+
return operations.map((operation) => {
|
|
113
|
+
const access = operation.access;
|
|
114
|
+
if (access === undefined || access.roleRequirements.length === 0)
|
|
115
|
+
return operation;
|
|
116
|
+
let changed = false;
|
|
117
|
+
const roleRequirements = access.roleRequirements.map((requirement) => {
|
|
118
|
+
const authored = labelByRole[requirement.role];
|
|
119
|
+
if (authored === undefined || authored === requirement.label)
|
|
120
|
+
return requirement;
|
|
121
|
+
changed = true;
|
|
122
|
+
return { ...requirement, label: authored };
|
|
123
|
+
});
|
|
124
|
+
return changed ? { ...operation, access: { ...access, roleRequirements } } : operation;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
89
127
|
/**
|
|
90
128
|
* Materialize the reusable Markdown fact consumed by the Roles and permissions
|
|
91
129
|
* topic. This function knows no application identity: different applications
|
|
@@ -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 * 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":"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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 +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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type ApplicationConnectionDocumentationFact } from './application-connection-documentation';
|
|
2
2
|
import { type ApplicationAuthenticationDocumentationFact } from './application-authentication-documentation';
|
|
3
3
|
import { type ApplicationIntegrationDocumentationFact } from './application-integration-documentation';
|
|
4
|
+
import { type ApplicationDomainDocumentationFact } from './application-domain-documentation';
|
|
4
5
|
import { type ApplicationAdministrationDocumentationFact } from './application-administration-documentation';
|
|
5
|
-
import { TechnicalDocumentationAccessClass, TechnicalDocumentationReaderAudience, TechnicalDocumentationUnitKind, type TechnicalDocumentationApplicabilityRequirementV1, type TechnicalDocumentationApiReferenceTargetV1, type TechnicalDocumentationUnitV1 } from '@wildo-ai/saas-specifications/technical-documentation';
|
|
6
|
+
import { TechnicalDocumentationAccessClass, TechnicalDocumentationEditorialStatus, TechnicalDocumentationReaderAudience, type TechnicalDocumentationAssetRequestV1, TechnicalDocumentationUnitKind, type TechnicalDocumentationApplicabilityRequirementV1, type TechnicalDocumentationApiReferenceTargetV1, type TechnicalDocumentationUnitV1 } from '@wildo-ai/saas-specifications/technical-documentation';
|
|
6
7
|
import { type EngineDocumentationSpecificationCatalogV1 } from '@wildo-ai/saas-specifications/companion';
|
|
7
8
|
import type { LoadedApplicationConsumerDocumentationContentBundleV1 } from '../content/application-consumer-documentation-content-loader';
|
|
8
9
|
import { APPLICATION_CONSUMER_DOCUMENTATION_COMPANION_PROJECTION_SOURCE_PREFIX } from '../../content/application-consumer-documentation-content-manifest.schemas';
|
|
@@ -17,6 +18,34 @@ export interface EngineContentUnitDefinition {
|
|
|
17
18
|
readonly label: string;
|
|
18
19
|
readonly target: TechnicalDocumentationApiReferenceTargetV1;
|
|
19
20
|
}[];
|
|
21
|
+
/**
|
|
22
|
+
* Editorial state of this page. **Omitted means `APPROVED`**, which is what every page authored
|
|
23
|
+
* before 2026-09-08 relied on — the two unit-creation sites hardcoded `APPROVED` and the policy's
|
|
24
|
+
* editorial suppression path therefore had no producer at all (#474).
|
|
25
|
+
*
|
|
26
|
+
* Declare `DRAFT` or `REVIEW_REQUIRED` for a page that exists in the content module and is not
|
|
27
|
+
* ready for a reader. It stays in the private derivation — so it is still built, still linked
|
|
28
|
+
* from the manifest, still visible to whoever is writing it — and the publication policy keeps it
|
|
29
|
+
* out of the portal with `EDITORIAL_NOT_APPROVED`. That is the difference between a page in
|
|
30
|
+
* progress and a page deleted, and until now the framework could only express the second.
|
|
31
|
+
*/
|
|
32
|
+
readonly editorialStatus?: TechnicalDocumentationEditorialStatus;
|
|
33
|
+
/**
|
|
34
|
+
* Assets this page asks for — a deterministic diagram, or a product screenshot.
|
|
35
|
+
*
|
|
36
|
+
* Omitted means none, which is what every page meant until 2026-09-08: both unit-creation sites
|
|
37
|
+
* hardcoded `assetRequests: []`, so the screenshot placeholder branch, the deterministic diagram
|
|
38
|
+
* renderer and the whole asset-resolution path were unreachable from shipped content (#474). The
|
|
39
|
+
* pipeline was complete and had no producer.
|
|
40
|
+
*
|
|
41
|
+
* A request is a DECLARATION that the page needs a picture, never a promise that one exists. The
|
|
42
|
+
* resolver decides what arrives: a `DETERMINISTIC_RENDER` diagram is materialized offline and
|
|
43
|
+
* arrives RESOLVED, while a `PLAYWRIGHT_CAPTURE` screenshot with no capture available ships a
|
|
44
|
+
* PLACEHOLDER and the page still publishes — skip the generation, never block the tree on a
|
|
45
|
+
* browser and a live stack. Whether provisional imagery may actually SHIP is an environment
|
|
46
|
+
* decision enforced at publication (`--refuse-provisional-assets`), not an authoring one.
|
|
47
|
+
*/
|
|
48
|
+
readonly assetRequests?: readonly TechnicalDocumentationAssetRequestV1[];
|
|
20
49
|
}
|
|
21
50
|
/** Public, semantic role inventory supplied by the resolved application companion. */
|
|
22
51
|
export interface ApplicationOrganizationRolesDocumentationFact {
|
|
@@ -32,6 +61,36 @@ export interface ApplicationOrganizationRolesDocumentationFact {
|
|
|
32
61
|
* and title; this map owns type, audience, publication posture and navigation
|
|
33
62
|
* relationships, allowing the projector to reject a mismatched content set.
|
|
34
63
|
*/
|
|
64
|
+
/**
|
|
65
|
+
* The unit-ref namespace generated resource pages live in, and the only place its shape is written.
|
|
66
|
+
*
|
|
67
|
+
* `technical-documentation:unit/manages/<resource>` — an ENGINE ref with a reserved segment, not an
|
|
68
|
+
* application-owned one. The distinction is load-bearing: `pathForUnit` still refuses a unit an
|
|
69
|
+
* application named, and these are engine units whose subject happens to come from the application.
|
|
70
|
+
*/
|
|
71
|
+
export declare function applicationDomainResourcePageUnitRef(resourceIdentifier: string): string;
|
|
72
|
+
/** The unit-ref prefix a renderer matches to recognise a generated resource page. */
|
|
73
|
+
export declare const APPLICATION_DOMAIN_RESOURCE_PAGE_UNIT_REF_PREFIX = "technical-documentation:unit/manages/";
|
|
74
|
+
/**
|
|
75
|
+
* Unit kinds this catalog deliberately produces NO unit for, each with the reason.
|
|
76
|
+
*
|
|
77
|
+
* The vocabulary has eight members and, until 2026-09-09, two of them had no producer at all — a
|
|
78
|
+
* silent gap, because a kind nobody authors looks exactly like a kind nobody needed (#474). RUNBOOK
|
|
79
|
+
* now has one. CHANGE does not, and the reason is structural rather than editorial:
|
|
80
|
+
*
|
|
81
|
+
* A CHANGE unit is a record of what changed in ONE application, so only that application could
|
|
82
|
+
* author it — and an application-authored unit cannot be routed. `pathForUnit` admits engine-
|
|
83
|
+
* namespaced slugs and the reserved `unit/manages/` namespace, and refuses everything else with
|
|
84
|
+
* "has no consumer navigation category". Application material reaches the site only as an ENGINE
|
|
85
|
+
* unit carrying application-projected facts, never as an application-authored page. So the engine
|
|
86
|
+
* cannot write a changelog it has no knowledge of, and the party that could has no door.
|
|
87
|
+
*
|
|
88
|
+
* The member is therefore kept rather than retired: what is missing is a route for
|
|
89
|
+
* application-authored units, not the concept. When that route exists, this entry is removed in the
|
|
90
|
+
* same change — and `technical-documentation-engine-content-bundle.test.ts` fails until it is,
|
|
91
|
+
* because the partition below is asserted total over the enum.
|
|
92
|
+
*/
|
|
93
|
+
export declare const ENGINE_CONTENT_UNIT_KINDS_WITHOUT_PRODUCER: Readonly<Partial<Record<TechnicalDocumentationUnitKind, string>>>;
|
|
35
94
|
export declare const ENGINE_CONTENT_UNIT_DEFINITIONS: Readonly<Record<string, EngineContentUnitDefinition>>;
|
|
36
95
|
/**
|
|
37
96
|
* The facts only the application knows, which the companion measures and passes in.
|
|
@@ -46,6 +105,7 @@ export interface ApplicationDocumentationFacts {
|
|
|
46
105
|
readonly authentication?: ApplicationAuthenticationDocumentationFact;
|
|
47
106
|
readonly administration?: ApplicationAdministrationDocumentationFact;
|
|
48
107
|
readonly integration?: ApplicationIntegrationDocumentationFact;
|
|
108
|
+
readonly domain?: ApplicationDomainDocumentationFact;
|
|
49
109
|
}
|
|
50
110
|
/**
|
|
51
111
|
* Compiles verified engine content and the application's own facts (organization roles,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-engine-content-bundle.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-engine-content-bundle.d.ts","sourceRoot":"","sources":["../../../../src/companion/application-documentation/technical-documentation-engine-content-bundle.ts"],"names":[],"mappings":"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"}
|