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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/esm/companion/application-documentation/application-administration-documentation.d.ts +52 -0
  2. package/dist/esm/companion/application-documentation/application-administration-documentation.d.ts.map +1 -0
  3. package/dist/esm/companion/application-documentation/application-administration-documentation.js +58 -0
  4. package/dist/esm/companion/application-documentation/application-administration-documentation.js.map +1 -0
  5. package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts +76 -0
  6. package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts.map +1 -0
  7. package/dist/esm/companion/application-documentation/application-authentication-documentation.js +116 -0
  8. package/dist/esm/companion/application-documentation/application-authentication-documentation.js.map +1 -0
  9. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts +111 -0
  10. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -0
  11. package/dist/esm/companion/application-documentation/application-connection-documentation.js +165 -0
  12. package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -0
  13. package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts +133 -0
  14. package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts.map +1 -0
  15. package/dist/esm/companion/application-documentation/application-domain-documentation.js +243 -0
  16. package/dist/esm/companion/application-documentation/application-domain-documentation.js.map +1 -0
  17. package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts +48 -0
  18. package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map +1 -0
  19. package/dist/esm/companion/application-documentation/application-integration-documentation.js +86 -0
  20. package/dist/esm/companion/application-documentation/application-integration-documentation.js.map +1 -0
  21. package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts +30 -0
  22. package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts.map +1 -1
  23. package/dist/esm/companion/application-documentation/application-organization-role-documentation.js +38 -0
  24. package/dist/esm/companion/application-documentation/application-organization-role-documentation.js.map +1 -1
  25. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts +82 -4
  26. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
  27. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js +412 -219
  28. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js.map +1 -1
  29. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts +10 -0
  30. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
  31. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js +9 -1
  32. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js.map +1 -1
  33. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js +1 -1
  34. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js.map +1 -1
  35. package/dist/esm/companion/index.d.ts +6 -1
  36. package/dist/esm/companion/index.d.ts.map +1 -1
  37. package/dist/esm/companion/index.js +6 -1
  38. package/dist/esm/companion/index.js.map +1 -1
  39. package/dist/esm/companion/manual-controller-route-projection.d.ts +112 -0
  40. package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -0
  41. package/dist/esm/companion/manual-controller-route-projection.js +249 -0
  42. package/dist/esm/companion/manual-controller-route-projection.js.map +1 -0
  43. package/dist/esm/companion/openapi-generator.d.ts +16 -0
  44. package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
  45. package/dist/esm/companion/openapi-generator.js +497 -32
  46. package/dist/esm/companion/openapi-generator.js.map +1 -1
  47. package/dist/esm/companion/operation-projection.schemas.d.ts +44 -0
  48. package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
  49. package/dist/esm/companion/operation-projection.schemas.js +37 -0
  50. package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
  51. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts +7 -1
  52. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
  53. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js +44 -20
  54. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js.map +1 -1
  55. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.d.ts.map +1 -1
  56. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js +8 -1
  57. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js.map +1 -1
  58. package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts +28 -0
  59. package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts.map +1 -0
  60. package/dist/esm/companion/rendering/technical-documentation-markdown-links.js +52 -0
  61. package/dist/esm/companion/rendering/technical-documentation-markdown-links.js.map +1 -0
  62. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts +0 -9
  63. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts.map +0 -1
  64. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js +0 -106
  65. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js.map +0 -1
  66. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts +1 -0
  67. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
  68. package/dist/esm/companion/rendering/technical-documentation-render-model.js +112 -88
  69. package/dist/esm/companion/rendering/technical-documentation-render-model.js.map +1 -1
  70. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts +10 -0
  71. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts.map +1 -1
  72. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.js +10 -15
  73. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.js.map +1 -1
  74. package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts +27 -1
  75. package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts.map +1 -1
  76. package/dist/esm/companion/technical-documentation-capture-execution-port.js.map +1 -1
  77. package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts +33 -0
  78. package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -0
  79. package/dist/esm/companion/technical-documentation-diagram-definitions.js +54 -0
  80. package/dist/esm/companion/technical-documentation-diagram-definitions.js.map +1 -0
  81. package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts +10 -18
  82. package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
  83. package/dist/esm/companion/technical-documentation-diagram-materializer.js +9 -39
  84. package/dist/esm/companion/technical-documentation-diagram-materializer.js.map +1 -1
  85. package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts +8 -4
  86. package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
  87. package/dist/esm/config/wildo-tech-doc-config.schemas.js +8 -4
  88. package/dist/esm/config/wildo-tech-doc-config.schemas.js.map +1 -1
  89. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +105 -122
  90. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
  91. package/dist/esm/content/application-consumer-documentation-content.techdoc.js +934 -2161
  92. package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
  93. package/dist/esm/runtime/DocsAuthContext.d.ts +16 -1
  94. package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
  95. package/dist/esm/runtime/DocsAuthContext.js +18 -2
  96. package/dist/esm/runtime/DocsAuthContext.js.map +1 -1
  97. package/dist/esm/runtime/decode-jwt-claims.d.ts +7 -4
  98. package/dist/esm/runtime/decode-jwt-claims.d.ts.map +1 -1
  99. package/dist/esm/runtime/decode-jwt-claims.js +7 -4
  100. package/dist/esm/runtime/decode-jwt-claims.js.map +1 -1
  101. package/dist/esm/runtime/docs-auth-session.schemas.d.ts +16 -5
  102. package/dist/esm/runtime/docs-auth-session.schemas.d.ts.map +1 -1
  103. package/dist/esm/runtime/docs-auth-session.schemas.js +16 -5
  104. package/dist/esm/runtime/docs-auth-session.schemas.js.map +1 -1
  105. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts +35 -13
  106. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
  107. package/dist/esm/runtime/frontend-provider-registry.techdoc.js +28 -19
  108. package/dist/esm/runtime/frontend-provider-registry.techdoc.js.map +1 -1
  109. package/dist/esm/runtime/index.d.ts +1 -0
  110. package/dist/esm/runtime/index.d.ts.map +1 -1
  111. package/dist/esm/runtime/index.js +1 -0
  112. package/dist/esm/runtime/index.js.map +1 -1
  113. package/dist/esm/runtime/use-docs-auth-session.d.ts +9 -7
  114. package/dist/esm/runtime/use-docs-auth-session.d.ts.map +1 -1
  115. package/dist/esm/runtime/use-docs-auth-session.js +9 -7
  116. package/dist/esm/runtime/use-docs-auth-session.js.map +1 -1
  117. package/dist/esm/runtime/use-docs-provider-sdks.d.ts +21 -0
  118. package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -0
  119. package/dist/esm/runtime/use-docs-provider-sdks.js +49 -0
  120. package/dist/esm/runtime/use-docs-provider-sdks.js.map +1 -0
  121. package/dist/tsconfig.build.tsbuildinfo +1 -1
  122. package/package.json +6 -5
  123. package/dist/esm/.builder.pid +0 -9
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Who may perform each administrative action in THIS application.
3
+ *
4
+ * The roles page lists the roles and what each is for; it could not say which role may actually
5
+ * invite a person, change their access or move a team, because that lives on the operations —
6
+ * every one of which declares the roles it accepts. An administrator's first question ("can a
7
+ * manager do this, or does it need an owner?") therefore had no answer anywhere in the portal, and
8
+ * the pages fell back on prose about least privilege.
9
+ *
10
+ * The projection joins two things the companion already holds: the admitted operations for the
11
+ * membership and organization-unit resources, and the application's own role labels. It is a
12
+ * matrix of what this application publishes, not a restatement of the framework's defaults.
13
+ */
14
+ export declare const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_REF: "source:companion-projection:application-administration";
15
+ export declare const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_VERSION = 1;
16
+ export interface ApplicationAdministrationActionSource {
17
+ /** What the action does, in the words the API reference uses for the same operation. */
18
+ readonly action: string;
19
+ /**
20
+ * Labels of the organization roles that may perform it, in the application's own words.
21
+ * Empty means the operation declares no role gate — see `openToEveryMember`.
22
+ */
23
+ readonly roleLabels: readonly string[];
24
+ /**
25
+ * True when the operation declares no required role. That is a real, intentional state (any
26
+ * authenticated member of the organization may call it), not a gap in the projection, so it is
27
+ * said explicitly rather than shown as an empty cell.
28
+ */
29
+ readonly openToEveryMember: boolean;
30
+ }
31
+ export interface ApplicationAdministrationDocumentationSource {
32
+ readonly memberActions: readonly ApplicationAdministrationActionSource[];
33
+ readonly organizationUnitActions: readonly ApplicationAdministrationActionSource[];
34
+ }
35
+ /** Named presentations a page may request with `{{APPLICATION_ADMINISTRATION:<selector>}}`. */
36
+ export declare enum ApplicationAdministrationPresentation {
37
+ /** Membership actions — invite, change access, suspend, remove — against the roles that may do them. */
38
+ MEMBER_ACTIONS = "memberActions",
39
+ /** Organization-unit actions against the roles that may do them. */
40
+ ORGANIZATION_UNIT_ACTIONS = "organizationUnitActions"
41
+ }
42
+ export interface ApplicationAdministrationDocumentationFact {
43
+ readonly sourceRef: string;
44
+ readonly sourceVersion: number;
45
+ readonly presentations: Readonly<Record<ApplicationAdministrationPresentation, string>>;
46
+ }
47
+ /**
48
+ * Projects the administrative matrix. A pure function of the source, so two runs over the same
49
+ * application produce identical bytes.
50
+ */
51
+ export declare function projectApplicationAdministrationDocumentation(source: ApplicationAdministrationDocumentationSource): ApplicationAdministrationDocumentationFact;
52
+ //# sourceMappingURL=application-administration-documentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-administration-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-administration-documentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mDAAmD,EAAG,wDAAiE,CAAC;AACrI,eAAO,MAAM,uDAAuD,IAAI,CAAC;AAEzE,MAAM,WAAW,qCAAqC;IACpD,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,CAAC,aAAa,EAAE,SAAS,qCAAqC,EAAE,CAAC;IACzE,QAAQ,CAAC,uBAAuB,EAAE,SAAS,qCAAqC,EAAE,CAAC;CACpF;AAED,+FAA+F;AAC/F,oBAAY,qCAAqC;IAC/C,wGAAwG;IACxG,cAAc,kBAAkB;IAChC,oEAAoE;IACpE,yBAAyB,4BAA4B;CACtD;AAED,MAAM,WAAW,0CAA0C;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,qCAAqC,EAAE,MAAM,CAAC,CAAC,CAAC;CACzF;AAoBD;;;GAGG;AACH,wBAAgB,6CAA6C,CAC3D,MAAM,EAAE,4CAA4C,GACnD,0CAA0C,CAoB5C"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Who may perform each administrative action in THIS application.
3
+ *
4
+ * The roles page lists the roles and what each is for; it could not say which role may actually
5
+ * invite a person, change their access or move a team, because that lives on the operations —
6
+ * every one of which declares the roles it accepts. An administrator's first question ("can a
7
+ * manager do this, or does it need an owner?") therefore had no answer anywhere in the portal, and
8
+ * the pages fell back on prose about least privilege.
9
+ *
10
+ * The projection joins two things the companion already holds: the admitted operations for the
11
+ * membership and organization-unit resources, and the application's own role labels. It is a
12
+ * matrix of what this application publishes, not a restatement of the framework's defaults.
13
+ */
14
+ export const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-administration';
15
+ export const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_VERSION = 1;
16
+ /** Named presentations a page may request with `{{APPLICATION_ADMINISTRATION:<selector>}}`. */
17
+ export var ApplicationAdministrationPresentation;
18
+ (function (ApplicationAdministrationPresentation) {
19
+ /** Membership actions — invite, change access, suspend, remove — against the roles that may do them. */
20
+ ApplicationAdministrationPresentation["MEMBER_ACTIONS"] = "memberActions";
21
+ /** Organization-unit actions against the roles that may do them. */
22
+ ApplicationAdministrationPresentation["ORGANIZATION_UNIT_ACTIONS"] = "organizationUnitActions";
23
+ })(ApplicationAdministrationPresentation || (ApplicationAdministrationPresentation = {}));
24
+ function actionsTable(actions, emptyMessage) {
25
+ if (actions.length === 0)
26
+ return emptyMessage;
27
+ const rows = actions
28
+ .map((action) => {
29
+ const who = action.openToEveryMember
30
+ ? 'Any active member of the organization'
31
+ : action.roleLabels.length === 0
32
+ ? 'Not published for organization roles'
33
+ : action.roleLabels.join(', ');
34
+ return `| ${action.action} | ${who} |`;
35
+ })
36
+ .join('\n');
37
+ return `| Action | Who may perform it |\n| --- | --- |\n${rows}\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 operation contract in the API reference is authoritative for one exact call.`;
38
+ }
39
+ /**
40
+ * Projects the administrative matrix. A pure function of the source, so two runs over the same
41
+ * application produce identical bytes.
42
+ */
43
+ export function projectApplicationAdministrationDocumentation(source) {
44
+ for (const action of [...source.memberActions, ...source.organizationUnitActions]) {
45
+ if (action.action.trim().length === 0) {
46
+ throw new Error('application administration projection received an action with no description');
47
+ }
48
+ }
49
+ return {
50
+ sourceRef: APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_REF,
51
+ sourceVersion: APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_VERSION,
52
+ presentations: Object.freeze({
53
+ [ApplicationAdministrationPresentation.MEMBER_ACTIONS]: actionsTable(source.memberActions, 'This application publishes no membership administration operations, so member access is managed outside this documentation.'),
54
+ [ApplicationAdministrationPresentation.ORGANIZATION_UNIT_ACTIONS]: actionsTable(source.organizationUnitActions, 'This application does not publish organization units, so there are no unit administration actions.'),
55
+ }),
56
+ };
57
+ }
58
+ //# sourceMappingURL=application-administration-documentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-administration-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-administration-documentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mDAAmD,GAAG,wDAAiE,CAAC;AACrI,MAAM,CAAC,MAAM,uDAAuD,GAAG,CAAC,CAAC;AAuBzE,+FAA+F;AAC/F,MAAM,CAAN,IAAY,qCAKX;AALD,WAAY,qCAAqC;IAC/C,wGAAwG;IACxG,yEAAgC,CAAA;IAChC,oEAAoE;IACpE,8FAAqD,CAAA;AACvD,CAAC,EALW,qCAAqC,KAArC,qCAAqC,QAKhD;AAQD,SAAS,YAAY,CACnB,OAAyD,EACzD,YAAoB;IAEpB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IAC9C,MAAM,IAAI,GAAG,OAAO;SACjB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,CAAC,iBAAiB;YAClC,CAAC,CAAC,uCAAuC;YACzC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;gBAC9B,CAAC,CAAC,sCAAsC;gBACxC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,KAAK,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC;IACzC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,mDAAmD,IAAI,wPAAwP,CAAC;AACzT,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6CAA6C,CAC3D,MAAoD;IAEpD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,MAAM,CAAC,aAAa,EAAE,GAAG,MAAM,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAClF,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IACD,OAAO;QACL,SAAS,EAAE,mDAAmD;QAC9D,aAAa,EAAE,uDAAuD;QACtE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;YAC3B,CAAC,qCAAqC,CAAC,cAAc,CAAC,EAAE,YAAY,CAClE,MAAM,CAAC,aAAa,EACpB,6HAA6H,CAC9H;YACD,CAAC,qCAAqC,CAAC,yBAAyB,CAAC,EAAE,YAAY,CAC7E,MAAM,CAAC,uBAAuB,EAC9B,oGAAoG,CACrG;SACF,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Who may perform each administrative action in THIS application.\n *\n * The roles page lists the roles and what each is for; it could not say which role may actually\n * invite a person, change their access or move a team, because that lives on the operations —\n * every one of which declares the roles it accepts. An administrator's first question (\"can a\n * manager do this, or does it need an owner?\") therefore had no answer anywhere in the portal, and\n * the pages fell back on prose about least privilege.\n *\n * The projection joins two things the companion already holds: the admitted operations for the\n * membership and organization-unit resources, and the application's own role labels. It is a\n * matrix of what this application publishes, not a restatement of the framework's defaults.\n */\nexport const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-administration' as const;\nexport const APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_VERSION = 1;\n\nexport interface ApplicationAdministrationActionSource {\n /** What the action does, in the words the API reference uses for the same operation. */\n readonly action: string;\n /**\n * Labels of the organization roles that may perform it, in the application's own words.\n * Empty means the operation declares no role gate — see `openToEveryMember`.\n */\n readonly roleLabels: readonly string[];\n /**\n * True when the operation declares no required role. That is a real, intentional state (any\n * authenticated member of the organization may call it), not a gap in the projection, so it is\n * said explicitly rather than shown as an empty cell.\n */\n readonly openToEveryMember: boolean;\n}\n\nexport interface ApplicationAdministrationDocumentationSource {\n readonly memberActions: readonly ApplicationAdministrationActionSource[];\n readonly organizationUnitActions: readonly ApplicationAdministrationActionSource[];\n}\n\n/** Named presentations a page may request with `{{APPLICATION_ADMINISTRATION:<selector>}}`. */\nexport enum ApplicationAdministrationPresentation {\n /** Membership actions — invite, change access, suspend, remove — against the roles that may do them. */\n MEMBER_ACTIONS = 'memberActions',\n /** Organization-unit actions against the roles that may do them. */\n ORGANIZATION_UNIT_ACTIONS = 'organizationUnitActions',\n}\n\nexport interface ApplicationAdministrationDocumentationFact {\n readonly sourceRef: string;\n readonly sourceVersion: number;\n readonly presentations: Readonly<Record<ApplicationAdministrationPresentation, string>>;\n}\n\nfunction actionsTable(\n actions: readonly ApplicationAdministrationActionSource[],\n emptyMessage: string,\n): string {\n if (actions.length === 0) return emptyMessage;\n const rows = actions\n .map((action) => {\n const who = action.openToEveryMember\n ? 'Any active member of the organization'\n : action.roleLabels.length === 0\n ? 'Not published for organization roles'\n : action.roleLabels.join(', ');\n return `| ${action.action} | ${who} |`;\n })\n .join('\\n');\n return `| Action | Who may perform it |\\n| --- | --- |\\n${rows}\\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 operation contract in the API reference is authoritative for one exact call.`;\n}\n\n/**\n * Projects the administrative matrix. A pure function of the source, so two runs over the same\n * application produce identical bytes.\n */\nexport function projectApplicationAdministrationDocumentation(\n source: ApplicationAdministrationDocumentationSource,\n): ApplicationAdministrationDocumentationFact {\n for (const action of [...source.memberActions, ...source.organizationUnitActions]) {\n if (action.action.trim().length === 0) {\n throw new Error('application administration projection received an action with no description');\n }\n }\n return {\n sourceRef: APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_REF,\n sourceVersion: APPLICATION_ADMINISTRATION_DOCUMENTATION_SOURCE_VERSION,\n presentations: Object.freeze({\n [ApplicationAdministrationPresentation.MEMBER_ACTIONS]: actionsTable(\n source.memberActions,\n 'This application publishes no membership administration operations, so member access is managed outside this documentation.',\n ),\n [ApplicationAdministrationPresentation.ORGANIZATION_UNIT_ACTIONS]: actionsTable(\n source.organizationUnitActions,\n 'This application does not publish organization units, so there are no unit administration actions.',\n ),\n }),\n };\n}\n"]}
@@ -0,0 +1,76 @@
1
+ import { AuthMethod } from '@wildo-ai/saas-models';
2
+ /**
3
+ * What THIS application actually asks of a person signing in.
4
+ *
5
+ * The engine catalogue can only say which sign-in methods exist. Three pages printed that
6
+ * catalogue and warned the reader it was "not a promise", which is honest and useless: a Wonder
7
+ * Todos reader was shown SMS codes and external identity providers the application never enables,
8
+ * and was told nothing about the password rules, the lockout, the session lifetime or how many
9
+ * recovery codes an enrolment hands out — all of which are configured, and all of which the
10
+ * companion can read.
11
+ *
12
+ * Policy is per user type by construction (`UserTypeAuthPolicy`), so the projection is too. A user
13
+ * type is shown by its configured key, not by an invented display name: the key is what the
14
+ * application calls that kind of account, and there is no label source that could say otherwise.
15
+ */
16
+ export declare const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_REF: "source:companion-projection:application-authentication";
17
+ export declare const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_VERSION = 1;
18
+ export interface ApplicationUserTypeAuthenticationSource {
19
+ /** The application's own key for this kind of account, for example `member` or `admin`. */
20
+ readonly userTypeKey: string;
21
+ /** Methods this application enables for the user type, in the engine's declaration order. */
22
+ readonly enabledMethods: readonly AuthMethod[];
23
+ readonly multifactor: {
24
+ readonly required: boolean;
25
+ readonly strongRequired: boolean;
26
+ readonly enrollmentGracePeriodDays: number;
27
+ readonly passkeyExemptFromMultifactor: boolean;
28
+ /** When set, the only second factors this application accepts. */
29
+ readonly acceptableMethods?: readonly AuthMethod[];
30
+ };
31
+ readonly password: {
32
+ readonly minLength: number;
33
+ readonly maxLength: number;
34
+ readonly requireUppercase: boolean;
35
+ readonly requireLowercase: boolean;
36
+ readonly requireNumbers: boolean;
37
+ readonly requireSpecialChars: boolean;
38
+ /** Days before a password must be changed. `0` means it does not expire. */
39
+ readonly expiryDays: number;
40
+ };
41
+ readonly session: {
42
+ readonly durationMinutes: number;
43
+ readonly maxConcurrentSessions?: number;
44
+ };
45
+ readonly lockout: {
46
+ readonly maxLoginAttempts: number;
47
+ readonly lockoutDurationMinutes: number;
48
+ readonly progressive: boolean;
49
+ readonly maxProgressiveLockoutHours: number;
50
+ };
51
+ }
52
+ export interface ApplicationAuthenticationDocumentationSource {
53
+ readonly userTypes: readonly ApplicationUserTypeAuthenticationSource[];
54
+ }
55
+ /** Named presentations a page may request with `{{APPLICATION_AUTHENTICATION:<selector>}}`. */
56
+ export declare enum ApplicationAuthenticationPresentation {
57
+ /** The sign-in methods this application enables, per user type. */
58
+ ENABLED_SIGN_IN_METHODS = "enabledSignInMethods",
59
+ /** Whether a second factor is required, which ones count, and what enrolment hands out. */
60
+ MULTIFACTOR_POLICY = "multifactorPolicy",
61
+ /** The password rules a person must satisfy. */
62
+ PASSWORD_RULES = "passwordRules",
63
+ /** How long a session lasts and what a run of failed attempts costs. */
64
+ SESSION_AND_LOCKOUT = "sessionAndLockout"
65
+ }
66
+ export interface ApplicationAuthenticationDocumentationFact {
67
+ readonly sourceRef: string;
68
+ readonly sourceVersion: number;
69
+ readonly presentations: Readonly<Record<ApplicationAuthenticationPresentation, string>>;
70
+ }
71
+ /**
72
+ * Projects the application's authentication policy into the presentations a page may request.
73
+ * A pure function of the source, so two runs over the same application produce identical bytes.
74
+ */
75
+ export declare function projectApplicationAuthenticationDocumentation(source: ApplicationAuthenticationDocumentationSource): ApplicationAuthenticationDocumentationFact;
76
+ //# sourceMappingURL=application-authentication-documentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-authentication-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-authentication-documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8D,MAAM,uBAAuB,CAAC;AAG/G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mDAAmD,EAAG,wDAAiE,CAAC;AACrI,eAAO,MAAM,uDAAuD,IAAI,CAAC;AAEzE,MAAM,WAAW,uCAAuC;IACtD,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;QACjC,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;QAC3C,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC;QAC/C,kEAAkE;QAClE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;KACpD,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;QACnC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;QACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;QACjC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;QACtC,4EAA4E;QAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;KACzC,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,0BAA0B,EAAE,MAAM,CAAC;KAC7C,CAAC;CACH;AAED,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,CAAC,SAAS,EAAE,SAAS,uCAAuC,EAAE,CAAC;CACxE;AAED,+FAA+F;AAC/F,oBAAY,qCAAqC;IAC/C,mEAAmE;IACnE,uBAAuB,yBAAyB;IAChD,2FAA2F;IAC3F,kBAAkB,sBAAsB;IACxC,gDAAgD;IAChD,cAAc,kBAAkB;IAChC,wEAAwE;IACxE,mBAAmB,sBAAsB;CAC1C;AAED,MAAM,WAAW,0CAA0C;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,qCAAqC,EAAE,MAAM,CAAC,CAAC,CAAC;CACzF;AAoED;;;GAGG;AACH,wBAAgB,6CAA6C,CAC3D,MAAM,EAAE,4CAA4C,GACnD,0CAA0C,CAmB5C"}
@@ -0,0 +1,116 @@
1
+ import { MFA_BACKUP_CODE_CHARACTER_LENGTH, MFA_BACKUP_CODE_CONTRACT } from '@wildo-ai/saas-models';
2
+ import { authenticationMethodConsumerWords } from '@wildo-ai/saas-specifications/companion';
3
+ /**
4
+ * What THIS application actually asks of a person signing in.
5
+ *
6
+ * The engine catalogue can only say which sign-in methods exist. Three pages printed that
7
+ * catalogue and warned the reader it was "not a promise", which is honest and useless: a Wonder
8
+ * Todos reader was shown SMS codes and external identity providers the application never enables,
9
+ * and was told nothing about the password rules, the lockout, the session lifetime or how many
10
+ * recovery codes an enrolment hands out — all of which are configured, and all of which the
11
+ * companion can read.
12
+ *
13
+ * Policy is per user type by construction (`UserTypeAuthPolicy`), so the projection is too. A user
14
+ * type is shown by its configured key, not by an invented display name: the key is what the
15
+ * application calls that kind of account, and there is no label source that could say otherwise.
16
+ */
17
+ export const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-authentication';
18
+ export const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_VERSION = 1;
19
+ /** Named presentations a page may request with `{{APPLICATION_AUTHENTICATION:<selector>}}`. */
20
+ export var ApplicationAuthenticationPresentation;
21
+ (function (ApplicationAuthenticationPresentation) {
22
+ /** The sign-in methods this application enables, per user type. */
23
+ ApplicationAuthenticationPresentation["ENABLED_SIGN_IN_METHODS"] = "enabledSignInMethods";
24
+ /** Whether a second factor is required, which ones count, and what enrolment hands out. */
25
+ ApplicationAuthenticationPresentation["MULTIFACTOR_POLICY"] = "multifactorPolicy";
26
+ /** The password rules a person must satisfy. */
27
+ ApplicationAuthenticationPresentation["PASSWORD_RULES"] = "passwordRules";
28
+ /** How long a session lasts and what a run of failed attempts costs. */
29
+ ApplicationAuthenticationPresentation["SESSION_AND_LOCKOUT"] = "sessionAndLockout";
30
+ })(ApplicationAuthenticationPresentation || (ApplicationAuthenticationPresentation = {}));
31
+ function methodNames(methods) {
32
+ if (methods.length === 0)
33
+ return 'None';
34
+ return methods.map((method) => authenticationMethodConsumerWords(method).name).join(', ');
35
+ }
36
+ function userTypeCell(userType) {
37
+ return `\`${userType.userTypeKey}\``;
38
+ }
39
+ function enabledSignInMethodsMarkdown(source) {
40
+ const rows = source.userTypes
41
+ .map((userType) => `| ${userTypeCell(userType)} | ${methodNames(userType.enabledMethods)} |`)
42
+ .join('\n');
43
+ return `| Account kind | Sign-in methods this application enables |\n| --- | --- |\n${rows}\n\nAn organization can narrow this further for its own people — for example by requiring its single sign-on — so the sign-in screen remains the last word on what you can use right now.`;
44
+ }
45
+ function multifactorPolicyMarkdown(source) {
46
+ const rows = source.userTypes.map((userType) => {
47
+ const { multifactor } = userType;
48
+ const required = multifactor.required
49
+ ? multifactor.strongRequired ? 'Required, and a phishing-resistant method is required' : 'Required'
50
+ : 'Optional';
51
+ const grace = multifactor.required && multifactor.enrollmentGracePeriodDays > 0
52
+ ? `${multifactor.enrollmentGracePeriodDays} day${multifactor.enrollmentGracePeriodDays === 1 ? '' : 's'} to enrol`
53
+ : multifactor.required ? 'No grace period' : '—';
54
+ const accepted = multifactor.acceptableMethods === undefined
55
+ ? 'Any second factor enabled above'
56
+ : methodNames(multifactor.acceptableMethods);
57
+ const passkey = multifactor.passkeyExemptFromMultifactor ? 'Yes' : 'No';
58
+ return `| ${userTypeCell(userType)} | ${required} | ${grace} | ${accepted} | ${passkey} |`;
59
+ }).join('\n');
60
+ const codes = `Enrolling an authenticator app also hands you **${MFA_BACKUP_CODE_CONTRACT.codeCount} recovery codes** of ${MFA_BACKUP_CODE_CHARACTER_LENGTH} characters each. ${MFA_BACKUP_CODE_CONTRACT.singleUse ? 'Each code works once and is gone when used' : 'Codes may be reused'}; the application stores only a hash of them, so nobody can read them back to you. Enrolling again replaces the whole set.`;
61
+ return `| Account kind | Second factor | Enrolment window | Accepted as a second factor | Passkey counts on its own |\n| --- | --- | --- | --- | --- |\n${rows}\n\n${codes}`;
62
+ }
63
+ function passwordRulesMarkdown(source) {
64
+ const rows = source.userTypes.map((userType) => {
65
+ const { password } = userType;
66
+ const classes = [
67
+ password.requireUppercase ? 'an uppercase letter' : null,
68
+ password.requireLowercase ? 'a lowercase letter' : null,
69
+ password.requireNumbers ? 'a digit' : null,
70
+ password.requireSpecialChars ? 'a special character' : null,
71
+ ].filter((requirement) => requirement !== null);
72
+ const composition = classes.length === 0 ? 'No character requirement' : `Must contain ${classes.join(', ')}`;
73
+ const expiry = password.expiryDays > 0 ? `Every ${password.expiryDays} days` : 'Never expires';
74
+ return `| ${userTypeCell(userType)} | ${password.minLength}–${password.maxLength} characters | ${composition} | ${expiry} |`;
75
+ }).join('\n');
76
+ return `| Account kind | Length | Composition | Change required |\n| --- | --- | --- | --- |\n${rows}`;
77
+ }
78
+ function sessionAndLockoutMarkdown(source) {
79
+ const rows = source.userTypes.map((userType) => {
80
+ const { session, lockout } = userType;
81
+ const concurrent = session.maxConcurrentSessions === undefined
82
+ ? 'Not limited'
83
+ : `${session.maxConcurrentSessions} at a time`;
84
+ const progressive = lockout.progressive
85
+ ? `, lengthening with each further run up to ${lockout.maxProgressiveLockoutHours} hours`
86
+ : '';
87
+ const lock = `${lockout.maxLoginAttempts} failed attempts lock the account for ${lockout.lockoutDurationMinutes} minutes${progressive}`;
88
+ return `| ${userTypeCell(userType)} | ${session.durationMinutes} minutes | ${concurrent} | ${lock} |`;
89
+ }).join('\n');
90
+ return `| Account kind | Session lasts | Concurrent sessions | Failed sign-ins |\n| --- | --- | --- | --- |\n${rows}\n\nA session ends when its time runs out, when you sign out, or when the application invalidates it — changing a password does exactly that, on every device.`;
91
+ }
92
+ /**
93
+ * Projects the application's authentication policy into the presentations a page may request.
94
+ * A pure function of the source, so two runs over the same application produce identical bytes.
95
+ */
96
+ export function projectApplicationAuthenticationDocumentation(source) {
97
+ if (source.userTypes.length === 0) {
98
+ throw new Error('application authentication projection requires at least one declared user type');
99
+ }
100
+ for (const userType of source.userTypes) {
101
+ if (userType.userTypeKey.trim().length === 0) {
102
+ throw new Error('application authentication projection received a user type with no key');
103
+ }
104
+ }
105
+ return {
106
+ sourceRef: APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_REF,
107
+ sourceVersion: APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_VERSION,
108
+ presentations: Object.freeze({
109
+ [ApplicationAuthenticationPresentation.ENABLED_SIGN_IN_METHODS]: enabledSignInMethodsMarkdown(source),
110
+ [ApplicationAuthenticationPresentation.MULTIFACTOR_POLICY]: multifactorPolicyMarkdown(source),
111
+ [ApplicationAuthenticationPresentation.PASSWORD_RULES]: passwordRulesMarkdown(source),
112
+ [ApplicationAuthenticationPresentation.SESSION_AND_LOCKOUT]: sessionAndLockoutMarkdown(source),
113
+ }),
114
+ };
115
+ }
116
+ //# sourceMappingURL=application-authentication-documentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-authentication-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-authentication-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthMethod, MFA_BACKUP_CODE_CHARACTER_LENGTH, MFA_BACKUP_CODE_CONTRACT } from '@wildo-ai/saas-models';\nimport { authenticationMethodConsumerWords } from '@wildo-ai/saas-specifications/companion';\n\n/**\n * What THIS application actually asks of a person signing in.\n *\n * The engine catalogue can only say which sign-in methods exist. Three pages printed that\n * catalogue and warned the reader it was \"not a promise\", which is honest and useless: a Wonder\n * Todos reader was shown SMS codes and external identity providers the application never enables,\n * and was told nothing about the password rules, the lockout, the session lifetime or how many\n * recovery codes an enrolment hands out — all of which are configured, and all of which the\n * companion can read.\n *\n * Policy is per user type by construction (`UserTypeAuthPolicy`), so the projection is too. A user\n * type is shown by its configured key, not by an invented display name: the key is what the\n * application calls that kind of account, and there is no label source that could say otherwise.\n */\nexport const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_REF = 'source:companion-projection:application-authentication' as const;\nexport const APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_VERSION = 1;\n\nexport interface ApplicationUserTypeAuthenticationSource {\n /** The application's own key for this kind of account, for example `member` or `admin`. */\n readonly userTypeKey: string;\n /** Methods this application enables for the user type, in the engine's declaration order. */\n readonly enabledMethods: readonly AuthMethod[];\n readonly multifactor: {\n readonly required: boolean;\n readonly strongRequired: boolean;\n readonly enrollmentGracePeriodDays: number;\n readonly passkeyExemptFromMultifactor: boolean;\n /** When set, the only second factors this application accepts. */\n readonly acceptableMethods?: readonly AuthMethod[];\n };\n readonly password: {\n readonly minLength: number;\n readonly maxLength: number;\n readonly requireUppercase: boolean;\n readonly requireLowercase: boolean;\n readonly requireNumbers: boolean;\n readonly requireSpecialChars: boolean;\n /** Days before a password must be changed. `0` means it does not expire. */\n readonly expiryDays: number;\n };\n readonly session: {\n readonly durationMinutes: number;\n readonly maxConcurrentSessions?: number;\n };\n readonly lockout: {\n readonly maxLoginAttempts: number;\n readonly lockoutDurationMinutes: number;\n readonly progressive: boolean;\n readonly maxProgressiveLockoutHours: number;\n };\n}\n\nexport interface ApplicationAuthenticationDocumentationSource {\n readonly userTypes: readonly ApplicationUserTypeAuthenticationSource[];\n}\n\n/** Named presentations a page may request with `{{APPLICATION_AUTHENTICATION:<selector>}}`. */\nexport enum ApplicationAuthenticationPresentation {\n /** The sign-in methods this application enables, per user type. */\n ENABLED_SIGN_IN_METHODS = 'enabledSignInMethods',\n /** Whether a second factor is required, which ones count, and what enrolment hands out. */\n MULTIFACTOR_POLICY = 'multifactorPolicy',\n /** The password rules a person must satisfy. */\n PASSWORD_RULES = 'passwordRules',\n /** How long a session lasts and what a run of failed attempts costs. */\n SESSION_AND_LOCKOUT = 'sessionAndLockout',\n}\n\nexport interface ApplicationAuthenticationDocumentationFact {\n readonly sourceRef: string;\n readonly sourceVersion: number;\n readonly presentations: Readonly<Record<ApplicationAuthenticationPresentation, string>>;\n}\n\nfunction methodNames(methods: readonly AuthMethod[]): string {\n if (methods.length === 0) return 'None';\n return methods.map((method) => authenticationMethodConsumerWords(method).name).join(', ');\n}\n\nfunction userTypeCell(userType: ApplicationUserTypeAuthenticationSource): string {\n return `\\`${userType.userTypeKey}\\``;\n}\n\nfunction enabledSignInMethodsMarkdown(source: ApplicationAuthenticationDocumentationSource): string {\n const rows = source.userTypes\n .map((userType) => `| ${userTypeCell(userType)} | ${methodNames(userType.enabledMethods)} |`)\n .join('\\n');\n return `| Account kind | Sign-in methods this application enables |\\n| --- | --- |\\n${rows}\\n\\nAn organization can narrow this further for its own people — for example by requiring its single sign-on — so the sign-in screen remains the last word on what you can use right now.`;\n}\n\nfunction multifactorPolicyMarkdown(source: ApplicationAuthenticationDocumentationSource): string {\n const rows = source.userTypes.map((userType) => {\n const { multifactor } = userType;\n const required = multifactor.required\n ? multifactor.strongRequired ? 'Required, and a phishing-resistant method is required' : 'Required'\n : 'Optional';\n const grace = multifactor.required && multifactor.enrollmentGracePeriodDays > 0\n ? `${multifactor.enrollmentGracePeriodDays} day${multifactor.enrollmentGracePeriodDays === 1 ? '' : 's'} to enrol`\n : multifactor.required ? 'No grace period' : '—';\n const accepted = multifactor.acceptableMethods === undefined\n ? 'Any second factor enabled above'\n : methodNames(multifactor.acceptableMethods);\n const passkey = multifactor.passkeyExemptFromMultifactor ? 'Yes' : 'No';\n return `| ${userTypeCell(userType)} | ${required} | ${grace} | ${accepted} | ${passkey} |`;\n }).join('\\n');\n const codes = `Enrolling an authenticator app also hands you **${MFA_BACKUP_CODE_CONTRACT.codeCount} recovery codes** of ${MFA_BACKUP_CODE_CHARACTER_LENGTH} characters each. ${MFA_BACKUP_CODE_CONTRACT.singleUse ? 'Each code works once and is gone when used' : 'Codes may be reused'}; the application stores only a hash of them, so nobody can read them back to you. Enrolling again replaces the whole set.`;\n return `| Account kind | Second factor | Enrolment window | Accepted as a second factor | Passkey counts on its own |\\n| --- | --- | --- | --- | --- |\\n${rows}\\n\\n${codes}`;\n}\n\nfunction passwordRulesMarkdown(source: ApplicationAuthenticationDocumentationSource): string {\n const rows = source.userTypes.map((userType) => {\n const { password } = userType;\n const classes = [\n password.requireUppercase ? 'an uppercase letter' : null,\n password.requireLowercase ? 'a lowercase letter' : null,\n password.requireNumbers ? 'a digit' : null,\n password.requireSpecialChars ? 'a special character' : null,\n ].filter((requirement): requirement is string => requirement !== null);\n const composition = classes.length === 0 ? 'No character requirement' : `Must contain ${classes.join(', ')}`;\n const expiry = password.expiryDays > 0 ? `Every ${password.expiryDays} days` : 'Never expires';\n return `| ${userTypeCell(userType)} | ${password.minLength}–${password.maxLength} characters | ${composition} | ${expiry} |`;\n }).join('\\n');\n return `| Account kind | Length | Composition | Change required |\\n| --- | --- | --- | --- |\\n${rows}`;\n}\n\nfunction sessionAndLockoutMarkdown(source: ApplicationAuthenticationDocumentationSource): string {\n const rows = source.userTypes.map((userType) => {\n const { session, lockout } = userType;\n const concurrent = session.maxConcurrentSessions === undefined\n ? 'Not limited'\n : `${session.maxConcurrentSessions} at a time`;\n const progressive = lockout.progressive\n ? `, lengthening with each further run up to ${lockout.maxProgressiveLockoutHours} hours`\n : '';\n const lock = `${lockout.maxLoginAttempts} failed attempts lock the account for ${lockout.lockoutDurationMinutes} minutes${progressive}`;\n return `| ${userTypeCell(userType)} | ${session.durationMinutes} minutes | ${concurrent} | ${lock} |`;\n }).join('\\n');\n return `| Account kind | Session lasts | Concurrent sessions | Failed sign-ins |\\n| --- | --- | --- | --- |\\n${rows}\\n\\nA session ends when its time runs out, when you sign out, or when the application invalidates it — changing a password does exactly that, on every device.`;\n}\n\n/**\n * Projects the application's authentication policy into the presentations a page may request.\n * A pure function of the source, so two runs over the same application produce identical bytes.\n */\nexport function projectApplicationAuthenticationDocumentation(\n source: ApplicationAuthenticationDocumentationSource,\n): ApplicationAuthenticationDocumentationFact {\n if (source.userTypes.length === 0) {\n throw new Error('application authentication projection requires at least one declared user type');\n }\n for (const userType of source.userTypes) {\n if (userType.userTypeKey.trim().length === 0) {\n throw new Error('application authentication projection received a user type with no key');\n }\n }\n return {\n sourceRef: APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_REF,\n sourceVersion: APPLICATION_AUTHENTICATION_DOCUMENTATION_SOURCE_VERSION,\n presentations: Object.freeze({\n [ApplicationAuthenticationPresentation.ENABLED_SIGN_IN_METHODS]: enabledSignInMethodsMarkdown(source),\n [ApplicationAuthenticationPresentation.MULTIFACTOR_POLICY]: multifactorPolicyMarkdown(source),\n [ApplicationAuthenticationPresentation.PASSWORD_RULES]: passwordRulesMarkdown(source),\n [ApplicationAuthenticationPresentation.SESSION_AND_LOCKOUT]: sessionAndLockoutMarkdown(source),\n }),\n };\n}\n"]}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The application's own name and the addresses an integrator connects to.
3
+ *
4
+ * Engine documentation is written once for every generated application, so it
5
+ * used to hedge everything an application knows about itself: "the server origin
6
+ * from this application's API reference", "the address published for this
7
+ * environment", "the application". Every one of those values is available to the
8
+ * companion at derivation time, and this projection is how they reach the page.
9
+ *
10
+ * The split is deliberate. The APPLICATION supplies what only it knows — its
11
+ * customer-facing name and the base URLs it publishes. The ENGINE supplies the
12
+ * paths, because a route is the engine's own contract and an application that
13
+ * restated it would hold a second copy that can drift (see
14
+ * `MANUAL_CONTROLLER_ROUTES_URLS`, whose values are mounted under
15
+ * `MAIN_API_BASE_PATH`). An endpoint appears only when the companion has
16
+ * observed that the application configures that surface, so a page never
17
+ * advertises a door this application does not open.
18
+ */
19
+ export declare const APPLICATION_CONNECTION_DOCUMENTATION_SOURCE_REF: "source:companion-projection:application-connection";
20
+ export declare const APPLICATION_CONNECTION_DOCUMENTATION_SOURCE_VERSION = 1;
21
+ /** One base URL an application publishes for an environment a reader may call. */
22
+ export interface ApplicationConnectionServer {
23
+ readonly url: string;
24
+ readonly description?: string;
25
+ }
26
+ /**
27
+ * What the companion measures about this application. `surfaces` mirrors the
28
+ * evidence the derivation already computes for applicability gating: the same
29
+ * observation that decides whether the MCP pages are published decides whether
30
+ * the MCP endpoint is printed, so a published address and a published page can
31
+ * never disagree.
32
+ */
33
+ export interface ApplicationConnectionDocumentationSource {
34
+ /** The name customers see. The application's `displayName`, else its `appName`. */
35
+ readonly applicationName: string;
36
+ /** Base URLs the application publishes, in the order it authored them. Possibly empty. */
37
+ readonly apiServers: readonly ApplicationConnectionServer[];
38
+ readonly surfaces: {
39
+ readonly mcpToolServer: boolean;
40
+ readonly a2aAgent: boolean;
41
+ };
42
+ }
43
+ /** Named presentations a page may request with `{{APPLICATION_CONNECTION:<selector>}}`. */
44
+ export declare enum ApplicationConnectionPresentation {
45
+ /** Every connection detail as one table: base URLs, the API mount, agent endpoints. */
46
+ CONNECTION_DETAILS = "connectionDetails",
47
+ /** The base URLs alone, for a page that only needs to say where requests go. */
48
+ BASE_URLS = "baseUrls",
49
+ /**
50
+ * The MCP endpoint sentence. Never empty: an application that exposes no MCP surface gets a
51
+ * sentence saying so. Projection runs for every unit and gating happens afterwards, so a
52
+ * presentation that rendered nothing would leave a blank where a suppressed page's prose was,
53
+ * and would say nothing at all if the page were ever published without its gate.
54
+ */
55
+ MCP_ENDPOINT = "mcpEndpoint",
56
+ /** The A2A agent-card sentence. Never empty, for the same reason as the MCP endpoint. */
57
+ A2A_AGENT_CARD = "a2aAgentCard"
58
+ }
59
+ /**
60
+ * Values a page substitutes INSIDE a sample — a JSON client configuration, an HTTP request line —
61
+ * where a block presentation cannot go. Each is a single string, never markdown.
62
+ */
63
+ export declare enum ApplicationConnectionInlineValue {
64
+ /** The first base URL the application publishes, or an explicit stand-in when it publishes none. */
65
+ BASE_URL = "baseUrl",
66
+ /** The full MCP endpoint URL a client configures. */
67
+ MCP_ENDPOINT_URL = "mcpEndpointUrl",
68
+ /** The full agent-card URL an A2A peer fetches. */
69
+ AGENT_CARD_URL = "agentCardUrl",
70
+ /** The full A2A task endpoint URL. */
71
+ AGENT_TASK_URL = "agentTaskUrl",
72
+ /**
73
+ * The full SCIM base URL an administrator pastes into their identity provider.
74
+ *
75
+ * Unlike the endpoints above this one is NOT gated on an observed surface, because SCIM is
76
+ * configured in the IdP rather than advertised by the application: the base is where traffic
77
+ * would be pushed, and whether a given organization has enabled provisioning is a tenant setting
78
+ * the page discusses separately. Derived from `SCIM_SERVICE_BASE_PATH` for the same reason the
79
+ * others derive from the route map — the engine owns the mount.
80
+ */
81
+ SCIM_BASE_URL = "scimBaseUrl",
82
+ /** The OAuth issuer a client configures, and checks the discovery document's `issuer` against. */
83
+ OAUTH_ISSUER = "oauthIssuer",
84
+ /**
85
+ * Where RFC 8414 authorization-server metadata is served.
86
+ *
87
+ * Derived with the engine's own `rfc8414AuthorizationServerMetadataPath`, never by appending the
88
+ * well-known segment to the issuer. The RFC inserts it BETWEEN the host and the issuer's path, so
89
+ * an issuer of `…/api/v1` publishes at `/.well-known/oauth-authorization-server/api/v1` — the
90
+ * opposite construction from OIDC discovery. Getting that backwards is not hypothetical: a real
91
+ * MCP client derived the RFC location, received the SPA shell, and abandoned authorization
92
+ * without opening a browser. Documentation that showed a hand-built path would be teaching the
93
+ * shape that failed.
94
+ */
95
+ OAUTH_METADATA_URL = "oauthMetadataUrl"
96
+ }
97
+ export interface ApplicationConnectionDocumentationFact {
98
+ readonly sourceRef: string;
99
+ readonly sourceVersion: number;
100
+ /** Substituted wherever a page writes the inline application-name token. */
101
+ readonly applicationName: string;
102
+ readonly presentations: Readonly<Record<ApplicationConnectionPresentation, string>>;
103
+ readonly inlineValues: Readonly<Record<ApplicationConnectionInlineValue, string>>;
104
+ }
105
+ /**
106
+ * Projects the application's connection facts into the presentations a page may
107
+ * request. Every presentation is a pure function of the source, so two runs over
108
+ * the same application produce identical bytes.
109
+ */
110
+ export declare function projectApplicationConnectionDocumentation(source: ApplicationConnectionDocumentationSource): ApplicationConnectionDocumentationFact;
111
+ //# sourceMappingURL=application-connection-documentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-connection-documentation.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-connection-documentation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,+CAA+C,EAAG,oDAA6D,CAAC;AAC7H,eAAO,MAAM,mDAAmD,IAAI,CAAC;AAErE,kFAAkF;AAClF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,wCAAwC;IACvD,mFAAmF;IACnF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,EAAE,SAAS,2BAA2B,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,2FAA2F;AAC3F,oBAAY,iCAAiC;IAC3C,uFAAuF;IACvF,kBAAkB,sBAAsB;IACxC,gFAAgF;IAChF,SAAS,aAAa;IACtB;;;;;OAKG;IACH,YAAY,gBAAgB;IAC5B,yFAAyF;IACzF,cAAc,iBAAiB;CAChC;AAED;;;GAGG;AACH,oBAAY,gCAAgC;IAC1C,oGAAoG;IACpG,QAAQ,YAAY;IACpB,qDAAqD;IACrD,gBAAgB,mBAAmB;IACnC,mDAAmD;IACnD,cAAc,iBAAiB;IAC/B,sCAAsC;IACtC,cAAc,iBAAiB;IAC/B;;;;;;;;OAQG;IACH,aAAa,gBAAgB;IAC7B,kGAAkG;IAClG,YAAY,gBAAgB;IAC5B;;;;;;;;;;OAUG;IACH,kBAAkB,qBAAqB;CACxC;AAED,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,iCAAiC,EAAE,MAAM,CAAC,CAAC,CAAC;IACpF,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC,CAAC;CACnF;AA0DD;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,MAAM,EAAE,wCAAwC,GAC/C,sCAAsC,CA2BxC"}