@wildo-ai/saas-technical-doc 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-authentication-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts.map +1 -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-operational-evidence.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
- package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.d.ts.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.map +1 -1
- package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -1
- package/dist/esm/companion/openapi-example-derivation.d.ts +53 -0
- package/dist/esm/companion/openapi-example-derivation.d.ts.map +1 -0
- package/dist/esm/companion/openapi-example-derivation.js +229 -0
- package/dist/esm/companion/openapi-example-derivation.js.map +1 -0
- package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
- package/dist/esm/companion/openapi-generator.js +284 -16
- package/dist/esm/companion/openapi-generator.js.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.d.ts +36 -0
- package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
- package/dist/esm/companion/operation-projection.schemas.js +18 -0
- package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
- package/dist/esm/companion/publish-result.types.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-authorized-bundle-reader.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js +20 -0
- package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts +2 -0
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js +48 -31
- package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
- package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts.map +1 -1
- package/dist/esm/companion/spec-to-operation-doc.d.ts +52 -10
- package/dist/esm/companion/spec-to-operation-doc.d.ts.map +1 -1
- package/dist/esm/companion/spec-to-operation-doc.js +125 -7
- package/dist/esm/companion/spec-to-operation-doc.js.map +1 -1
- package/dist/esm/companion/technical-documentation-asset-path.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
- package/dist/esm/companion/technical-documentation-placeholder-materializer.d.ts.map +1 -1
- package/dist/esm/companion/zod-to-openapi.d.ts.map +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/config/define-tech-doc-config.d.ts.map +1 -1
- package/dist/esm/config/index.d.ts.map +1 -1
- package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content-manifest.schemas.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +10 -10
- package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
- package/dist/esm/content/application-consumer-documentation-content.techdoc.js +43 -28
- package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
- package/dist/esm/content.exports.d.ts.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-link-index.d.ts +3 -0
- package/dist/esm/openapi/api-reference-link-index.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-link-index.js +26 -15
- package/dist/esm/openapi/api-reference-link-index.js.map +1 -1
- package/dist/esm/openapi/api-reference-pages.d.ts +55 -0
- package/dist/esm/openapi/api-reference-pages.d.ts.map +1 -0
- package/dist/esm/openapi/api-reference-pages.js +229 -0
- package/dist/esm/openapi/api-reference-pages.js.map +1 -0
- package/dist/esm/openapi/api-reference-search.d.ts +53 -0
- package/dist/esm/openapi/api-reference-search.d.ts.map +1 -0
- package/dist/esm/openapi/api-reference-search.js +100 -0
- package/dist/esm/openapi/api-reference-search.js.map +1 -0
- package/dist/esm/openapi/api-reference-targets.d.ts +11 -0
- package/dist/esm/openapi/api-reference-targets.d.ts.map +1 -1
- package/dist/esm/openapi/api-reference-targets.js +8 -0
- package/dist/esm/openapi/api-reference-targets.js.map +1 -1
- package/dist/esm/openapi/index.d.ts +2 -0
- package/dist/esm/openapi/index.d.ts.map +1 -1
- package/dist/esm/openapi/index.js +2 -0
- package/dist/esm/openapi/index.js.map +1 -1
- package/dist/esm/openapi/openapi-generation-output.schemas.d.ts.map +1 -1
- package/dist/esm/openapi-reference-model.exports.d.ts +2 -0
- package/dist/esm/openapi-reference-model.exports.d.ts.map +1 -1
- package/dist/esm/openapi-reference-model.exports.js +2 -0
- package/dist/esm/openapi-reference-model.exports.js.map +1 -1
- package/dist/esm/runtime/AuthExchangePage.d.ts +45 -4
- package/dist/esm/runtime/AuthExchangePage.d.ts.map +1 -1
- package/dist/esm/runtime/AuthExchangePage.js +45 -12
- package/dist/esm/runtime/AuthExchangePage.js.map +1 -1
- package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
- package/dist/esm/runtime/DocsFrontendProviders.d.ts +15 -1
- package/dist/esm/runtime/DocsFrontendProviders.d.ts.map +1 -1
- package/dist/esm/runtime/DocsFrontendProviders.js +16 -3
- package/dist/esm/runtime/DocsFrontendProviders.js.map +1 -1
- package/dist/esm/runtime/DocsProviderComponent.d.ts +41 -0
- package/dist/esm/runtime/DocsProviderComponent.d.ts.map +1 -0
- package/dist/esm/runtime/DocsProviderComponent.js +17 -0
- package/dist/esm/runtime/DocsProviderComponent.js.map +1 -0
- package/dist/esm/runtime/decode-jwt-claims.d.ts.map +1 -1
- package/dist/esm/runtime/docs-auth-client.d.ts.map +1 -1
- package/dist/esm/runtime/docs-auth-session.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/documentation-site-translator.d.ts +53 -0
- package/dist/esm/runtime/documentation-site-translator.d.ts.map +1 -0
- package/dist/esm/runtime/documentation-site-translator.js +51 -0
- package/dist/esm/runtime/documentation-site-translator.js.map +1 -0
- package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
- package/dist/esm/runtime/index.d.ts +6 -0
- package/dist/esm/runtime/index.d.ts.map +1 -1
- package/dist/esm/runtime/index.js +6 -0
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-conservation.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-model.d.ts +25 -0
- package/dist/esm/runtime/openapi-reference-model.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-model.js +82 -13
- package/dist/esm/runtime/openapi-reference-model.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-navigation.d.ts +50 -0
- package/dist/esm/runtime/openapi-reference-navigation.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-navigation.js +46 -0
- package/dist/esm/runtime/openapi-reference-navigation.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-samples.d.ts +40 -0
- package/dist/esm/runtime/openapi-reference-samples.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-samples.js +169 -0
- package/dist/esm/runtime/openapi-reference-samples.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-styles.d.ts +28 -0
- package/dist/esm/runtime/openapi-reference-styles.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-styles.js +292 -0
- package/dist/esm/runtime/openapi-reference-styles.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-view.d.ts +40 -5
- package/dist/esm/runtime/openapi-reference-view.d.ts.map +1 -1
- package/dist/esm/runtime/openapi-reference-view.js +828 -82
- package/dist/esm/runtime/openapi-reference-view.js.map +1 -1
- package/dist/esm/runtime/openapi-reference-words-context.d.ts +12 -0
- package/dist/esm/runtime/openapi-reference-words-context.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-words-context.js +30 -0
- package/dist/esm/runtime/openapi-reference-words-context.js.map +1 -0
- package/dist/esm/runtime/openapi-reference-words.d.ts +205 -0
- package/dist/esm/runtime/openapi-reference-words.d.ts.map +1 -0
- package/dist/esm/runtime/openapi-reference-words.js +162 -0
- package/dist/esm/runtime/openapi-reference-words.js.map +1 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.d.ts +31 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.d.ts.map +1 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.js +35 -0
- package/dist/esm/runtime/provider-component-registry.techdoc.js.map +1 -0
- package/dist/esm/runtime/use-docs-auth-session.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-provider-component.d.ts +29 -0
- package/dist/esm/runtime/use-docs-provider-component.d.ts.map +1 -0
- package/dist/esm/runtime/use-docs-provider-component.js +42 -0
- package/dist/esm/runtime/use-docs-provider-component.js.map +1 -0
- package/dist/esm/runtime/use-docs-provider-scripts.d.ts +12 -5
- package/dist/esm/runtime/use-docs-provider-scripts.d.ts.map +1 -1
- package/dist/esm/runtime/use-docs-provider-scripts.js +15 -8
- package/dist/esm/runtime/use-docs-provider-scripts.js.map +1 -1
- package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { TechnicalDocumentationOutputKind, TechnicalDocumentationRendererKind } from '@wildo-ai/saas-specifications/technical-documentation';
|
|
2
2
|
import { stringify as stringifyYaml } from 'yaml';
|
|
3
|
+
import { buildApiReferenceSearchIndex } from '../../openapi/api-reference-search.js';
|
|
3
4
|
import { OPENAPI_OUTPUT_FILENAMES, } from '../../openapi/openapi-generation-output.schemas.js';
|
|
4
5
|
import { createTechnicalDocumentationRendererExecution, } from './technical-documentation-render-model.js';
|
|
5
6
|
const OPENAPI_RENDERER_REF = 'technical-documentation:renderer/openapi';
|
|
7
|
+
/** Where the API reference's search entries land, relative to the generated API-reference root. */
|
|
8
|
+
export const API_REFERENCE_SEARCH_INDEX_RELATIVE_PATH = 'indexes/api-reference-search.json';
|
|
6
9
|
export function renderVerifiedTechnicalDocumentationOpenApi(input) {
|
|
7
10
|
if (input.sourceUnitRefs.length === 0)
|
|
8
11
|
throw new Error('technical-documentation OpenAPI rendering requires authorized source units');
|
|
@@ -13,39 +16,53 @@ export function renderVerifiedTechnicalDocumentationOpenApi(input) {
|
|
|
13
16
|
rendererVersion: 1,
|
|
14
17
|
configurationRef: 'technical-documentation:renderer-configuration/openapi-3-1-0',
|
|
15
18
|
}),
|
|
16
|
-
files: input.documents.sections.flatMap((section) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
files: [...input.documents.sections.flatMap((section) => {
|
|
20
|
+
const sectionPath = section.section.toLowerCase().replaceAll('_', '-');
|
|
21
|
+
const sourceUnitRefs = [...input.sourceUnitRefs].sort();
|
|
22
|
+
const filenames = OPENAPI_OUTPUT_FILENAMES[section.section];
|
|
23
|
+
const yaml = stringifyYaml(section.document, { lineWidth: 0, sortMapEntries: false });
|
|
24
|
+
const json = `${JSON.stringify(section.document, null, 2)}\n`;
|
|
25
|
+
/**
|
|
26
|
+
* YAML and JSON are two deterministic serializations of one generator
|
|
27
|
+
* document. YAML is the reviewable/downloadable contract; JSON is the
|
|
28
|
+
* browser renderer input. Neither file contains renderer-authored API
|
|
29
|
+
* meaning.
|
|
30
|
+
*/
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
outputRef: `technical-documentation:output/openapi/${sectionPath}/yaml`,
|
|
34
|
+
rendererRef: OPENAPI_RENDERER_REF,
|
|
35
|
+
outputKind: TechnicalDocumentationOutputKind.OPENAPI_DOCUMENT,
|
|
36
|
+
sourceUnitRefs,
|
|
37
|
+
normalizedRelativePath: `openapi/${filenames.yaml}`,
|
|
38
|
+
mediaType: 'application/yaml',
|
|
39
|
+
bytes: Buffer.from(yaml, 'utf8'),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
outputRef: `technical-documentation:output/openapi/${sectionPath}/json`,
|
|
43
|
+
rendererRef: OPENAPI_RENDERER_REF,
|
|
44
|
+
outputKind: TechnicalDocumentationOutputKind.OPENAPI_DOCUMENT,
|
|
45
|
+
sourceUnitRefs,
|
|
46
|
+
normalizedRelativePath: `openapi/${filenames.json}`,
|
|
47
|
+
mediaType: 'application/json',
|
|
48
|
+
bytes: Buffer.from(json, 'utf8'),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}),
|
|
22
52
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* meaning.
|
|
53
|
+
* The API reference's entries in the site search (#1624): one per resource and per operation,
|
|
54
|
+
* derived from the documents above so a result can only name what the reference serves. Emitted
|
|
55
|
+
* even with no section, so the site's search page always has the file it imports.
|
|
27
56
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
outputRef: `technical-documentation:output/openapi/${sectionPath}/json`,
|
|
40
|
-
rendererRef: OPENAPI_RENDERER_REF,
|
|
41
|
-
outputKind: TechnicalDocumentationOutputKind.OPENAPI_DOCUMENT,
|
|
42
|
-
sourceUnitRefs,
|
|
43
|
-
normalizedRelativePath: `openapi/${filenames.json}`,
|
|
44
|
-
mediaType: 'application/json',
|
|
45
|
-
bytes: Buffer.from(json, 'utf8'),
|
|
46
|
-
},
|
|
47
|
-
];
|
|
48
|
-
}),
|
|
57
|
+
{
|
|
58
|
+
outputRef: 'technical-documentation:output/openapi/search-index',
|
|
59
|
+
rendererRef: OPENAPI_RENDERER_REF,
|
|
60
|
+
outputKind: TechnicalDocumentationOutputKind.NAVIGATION_INDEX,
|
|
61
|
+
sourceUnitRefs: [...input.sourceUnitRefs].sort(),
|
|
62
|
+
normalizedRelativePath: API_REFERENCE_SEARCH_INDEX_RELATIVE_PATH,
|
|
63
|
+
mediaType: 'application/json',
|
|
64
|
+
bytes: Buffer.from(`${JSON.stringify(buildApiReferenceSearchIndex(input.documents.sections))}\n`, 'utf8'),
|
|
65
|
+
}],
|
|
49
66
|
};
|
|
50
67
|
}
|
|
51
68
|
//# sourceMappingURL=technical-documentation-openapi-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-openapi-renderer.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-openapi-renderer.js","sourceRoot":"","sources":["../../../../src/companion/rendering/technical-documentation-openapi-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { TechnicalDocumentationOutputKind, TechnicalDocumentationRendererKind } from '@wildo-ai/saas-specifications/technical-documentation';\nimport { stringify as stringifyYaml } from 'yaml';\n\nimport { buildApiReferenceSearchIndex } from '../../openapi/api-reference-search';\nimport {\n OPENAPI_OUTPUT_FILENAMES,\n type OpenApiGenerationOutput,\n} from '../../openapi/openapi-generation-output.schemas';\nimport {\n createTechnicalDocumentationRendererExecution,\n type TechnicalDocumentationRendererResult,\n} from './technical-documentation-render-model';\n\nconst OPENAPI_RENDERER_REF = 'technical-documentation:renderer/openapi';\n\n/** Where the API reference's search entries land, relative to the generated API-reference root. */\nexport const API_REFERENCE_SEARCH_INDEX_RELATIVE_PATH = 'indexes/api-reference-search.json';\n\nexport function renderVerifiedTechnicalDocumentationOpenApi(input: {\n readonly documents: OpenApiGenerationOutput;\n readonly sourceUnitRefs: readonly string[];\n}): TechnicalDocumentationRendererResult {\n if (input.sourceUnitRefs.length === 0) throw new Error('technical-documentation OpenAPI rendering requires authorized source units');\n return {\n execution: createTechnicalDocumentationRendererExecution({\n rendererKind: TechnicalDocumentationRendererKind.OPENAPI,\n rendererRef: OPENAPI_RENDERER_REF,\n rendererVersion: 1,\n configurationRef: 'technical-documentation:renderer-configuration/openapi-3-1-0',\n }),\n files: [...input.documents.sections.flatMap((section) => {\n const sectionPath = section.section.toLowerCase().replaceAll('_', '-');\n const sourceUnitRefs = [...input.sourceUnitRefs].sort();\n const filenames = OPENAPI_OUTPUT_FILENAMES[section.section];\n const yaml = stringifyYaml(section.document, { lineWidth: 0, sortMapEntries: false });\n const json = `${JSON.stringify(section.document, null, 2)}\\n`;\n /**\n * YAML and JSON are two deterministic serializations of one generator\n * document. YAML is the reviewable/downloadable contract; JSON is the\n * browser renderer input. Neither file contains renderer-authored API\n * meaning.\n */\n return [\n {\n outputRef: `technical-documentation:output/openapi/${sectionPath}/yaml`,\n rendererRef: OPENAPI_RENDERER_REF,\n outputKind: TechnicalDocumentationOutputKind.OPENAPI_DOCUMENT,\n sourceUnitRefs,\n normalizedRelativePath: `openapi/${filenames.yaml}`,\n mediaType: 'application/yaml',\n bytes: Buffer.from(yaml, 'utf8'),\n },\n {\n outputRef: `technical-documentation:output/openapi/${sectionPath}/json`,\n rendererRef: OPENAPI_RENDERER_REF,\n outputKind: TechnicalDocumentationOutputKind.OPENAPI_DOCUMENT,\n sourceUnitRefs,\n normalizedRelativePath: `openapi/${filenames.json}`,\n mediaType: 'application/json',\n bytes: Buffer.from(json, 'utf8'),\n },\n ] as const;\n }),\n /**\n * The API reference's entries in the site search (#1624): one per resource and per operation,\n * derived from the documents above so a result can only name what the reference serves. Emitted\n * even with no section, so the site's search page always has the file it imports.\n */\n {\n outputRef: 'technical-documentation:output/openapi/search-index',\n rendererRef: OPENAPI_RENDERER_REF,\n outputKind: TechnicalDocumentationOutputKind.NAVIGATION_INDEX,\n sourceUnitRefs: [...input.sourceUnitRefs].sort(),\n normalizedRelativePath: API_REFERENCE_SEARCH_INDEX_RELATIVE_PATH,\n mediaType: 'application/json',\n bytes: Buffer.from(`${JSON.stringify(buildApiReferenceSearchIndex(input.documents.sections))}\\n`, 'utf8'),\n }],\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-render-model.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-render-model.d.ts","sourceRoot":"","sources":["../../../../src/companion/rendering/technical-documentation-render-model.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,gCAAgC,EAEhC,kCAAkC,EAClC,KAAK,gDAAgD,EACrD,KAAK,4CAA4C,EACjD,KAAK,yCAAyC,EAC9C,KAAK,yCAAyC,EAC9C,KAAK,mDAAmD,EACxD,KAAK,yCAAyC,EAC9C,KAAK,4BAA4B,EAClC,MAAM,uDAAuD,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE3E;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,wBAAwB,EAAE,yCAAyC,CAAC;IAC7E,QAAQ,CAAC,OAAO,EAAE,gDAAgD,CAAC,SAAS,CAAC,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,SAAS,4BAA4B,EAAE,CAAC;IACxD,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,gCAAgC,CAAC;IACtD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,SAAS,EAAE,yCAAyC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,SAAS,kCAAkC,EAAE,CAAC;CAC/D;AAED,wBAAgB,6CAA6C,CAAC,KAAK,EAAE;IACnE,QAAQ,CAAC,YAAY,EAAE,kCAAkC,CAAC;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,kGAAkG;IAClG,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC,GAAG,yCAAyC,CAa5C;AA4FD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAoD,CAAC;AA8DxG,wBAAgB,uCAAuC,CACrD,gBAAgB,EAAE,gDAAgD,GACjE,iCAAiC,CAenC;AAED,wBAAgB,mDAAmD,CAAC,KAAK,EAAE;IACzE,QAAQ,CAAC,gBAAgB,EAAE,gDAAgD,CAAC;IAC5E,QAAQ,CAAC,mBAAmB,EAAE,mDAAmD,CAAC;IAClF,QAAQ,CAAC,mBAAmB,EAAE,yCAAyC,CAAC;IACxE,QAAQ,CAAC,eAAe,EAAE,SAAS,oCAAoC,EAAE,CAAC;IAC1E,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GAAG,4CAA4C,CAsB/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-search-index-renderer.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-search-index-renderer.d.ts","sourceRoot":"","sources":["../../../../src/companion/rendering/technical-documentation-search-index-renderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iCAAiC,EACtC,KAAK,oCAAoC,EAC1C,MAAM,wCAAwC,CAAC;AAIhD;;;;;;;;;GASG;AACH,wBAAgB,yCAAyC,CAAC,KAAK,EAAE,iCAAiC,GAAG,oCAAoC,CA6BxI"}
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* - **Tier 2** `injectFieldDocsIntoJsonSchema` — per-field `meaning` /
|
|
11
11
|
* `whyItMatters` / `relationshipContext` / enum-value meanings → property
|
|
12
12
|
* `description` + `x-enum-descriptions` on a request/response JSON-Schema
|
|
13
|
-
* fragment
|
|
13
|
+
* fragment; `injectFieldDocsIntoCollectionContract` applies the same to a
|
|
14
|
+
* paginated collection's `filters` bag and `data[]` items.
|
|
14
15
|
*
|
|
15
16
|
* See `.claude/plans/technical-doc-openapi-spec-integration.md`. Without authored
|
|
16
17
|
* spec prose the description is empty and the operation falls back to the
|
|
@@ -130,23 +131,64 @@ export interface FieldDoc {
|
|
|
130
131
|
* Joins by EXACT property-name match — DTO property names that diverge from
|
|
131
132
|
* the resource's field names (renamed / computed / backend-stripped fields)
|
|
132
133
|
* are simply left undocumented rather than mis-documented.
|
|
134
|
+
*
|
|
135
|
+
* "Top level" includes each branch of a top-level `oneOf` / `anyOf` / `allOf`.
|
|
136
|
+
* A polymorphic resource's representation is a union whose branches carry the
|
|
137
|
+
* properties themselves — the fragment has no `properties` of its own — and
|
|
138
|
+
* every branch's properties are still the resource's own top-level fields. Only
|
|
139
|
+
* composition keywords are entered, never an object property, so the rule above
|
|
140
|
+
* still holds. Without this, 42 of the 58 properties of Wonder Todos' `todos`
|
|
141
|
+
* read and list representations (`title`, `status`, `priority`, …) carried no
|
|
142
|
+
* description.
|
|
143
|
+
*
|
|
144
|
+
* A paginated collection re-wraps those fields one level down; see
|
|
145
|
+
* `injectFieldDocsIntoCollectionContract` for the two containers it adds.
|
|
133
146
|
*/
|
|
134
147
|
export declare const injectFieldDocsIntoJsonSchema: (fragment: unknown, fieldDocsByName: Record<string, FieldDoc>) => void;
|
|
148
|
+
/**
|
|
149
|
+
* Enrich the two places a paginated collection contract carries the resource's OWN fields one
|
|
150
|
+
* level down, where `injectFieldDocsIntoJsonSchema` (top level only) cannot reach them:
|
|
151
|
+
*
|
|
152
|
+
* - the request's `filters` object — one property per filterable field, which the generator
|
|
153
|
+
* flattens into query parameters (`?status=…`), copying each property's `description`;
|
|
154
|
+
* - the response envelope's `data[]` items — the resource rows a LIST / SEARCH returns.
|
|
155
|
+
*
|
|
156
|
+
* This is not the general nested walk `injectFieldDocsIntoJsonSchema` declines: a nested object's
|
|
157
|
+
* properties have no field specification, while these two containers hold the resource's own
|
|
158
|
+
* top-level fields, re-wrapped by the framework's collection contract. Before this, 59% of the
|
|
159
|
+
* list-item properties and 219 query filters in the Wonder Todos document carried no description,
|
|
160
|
+
* although the same fields were fully described in the read and create responses.
|
|
161
|
+
*
|
|
162
|
+
* Call it only for a paginated collection operation (LIST, or SEARCH-like). Anything else passes
|
|
163
|
+
* through unchanged, because neither container exists.
|
|
164
|
+
*/
|
|
165
|
+
export declare const injectFieldDocsIntoCollectionContract: (requestBodySchema: unknown, responseBodySchema: unknown, fieldDocsByName: Record<string, FieldDoc>) => void;
|
|
135
166
|
/**
|
|
136
167
|
* Projection-shaped HTTP documentation for one operation (Tier 3). Mirrors the
|
|
137
168
|
* authored `ResourceOperationSpecification` HTTP fields, normalized to plain
|
|
138
169
|
* JSON the OpenAPI generator emits as `responses` / `examples` / extensions.
|
|
139
170
|
*/
|
|
171
|
+
/**
|
|
172
|
+
* One documented failure mode, with the error-body field each identifier appears in.
|
|
173
|
+
*
|
|
174
|
+
* `errorType` is `error.type`, `customMessageReference` is `error.customMessageReference`, and
|
|
175
|
+
* `errorCode` is `error.code` — three different fields a client branches on, carried separately
|
|
176
|
+
* because the authored specification names them separately (see
|
|
177
|
+
* `ResourceOperationErrorScenarioSpecification`). Values are the wire strings.
|
|
178
|
+
*/
|
|
179
|
+
export interface OperationErrorScenarioDoc {
|
|
180
|
+
code: string;
|
|
181
|
+
when: string;
|
|
182
|
+
errorType?: string;
|
|
183
|
+
customMessageReference?: string;
|
|
184
|
+
errorCode?: string;
|
|
185
|
+
}
|
|
140
186
|
export interface OperationHttpDoc {
|
|
141
187
|
responseStatuses?: Array<{
|
|
142
188
|
code: string;
|
|
143
189
|
meaning: string;
|
|
144
190
|
}>;
|
|
145
|
-
errorScenarios?:
|
|
146
|
-
code: string;
|
|
147
|
-
when: string;
|
|
148
|
-
errorCode?: string;
|
|
149
|
-
}>;
|
|
191
|
+
errorScenarios?: OperationErrorScenarioDoc[];
|
|
150
192
|
idempotent?: boolean;
|
|
151
193
|
rateLimitNote?: string;
|
|
152
194
|
examples?: Array<{
|
|
@@ -167,10 +209,10 @@ export interface OperationHttpDoc {
|
|
|
167
209
|
*
|
|
168
210
|
* Prose fields (`meaning` / `when` / `title` / `rateLimitNote`) are cleaned of
|
|
169
211
|
* implementation-only noise via `asCleanProse`, consistent with the Tier-1
|
|
170
|
-
* `description` and Tier-2 field descriptions. `code` / `forStatus`
|
|
171
|
-
* `
|
|
172
|
-
*
|
|
173
|
-
*
|
|
212
|
+
* `description` and Tier-2 field descriptions. `code` / `forStatus` are
|
|
213
|
+
* `HttpResponseStatusCode` values whose runtime string (`'200'`, …) is the OpenAPI
|
|
214
|
+
* `responses` key; `errorType` / `customMessageReference` / `errorCode` are the
|
|
215
|
+
* error-body wire values a client branches on. All pass through untouched.
|
|
174
216
|
*/
|
|
175
217
|
export declare const buildOperationHttpDocFromSpec: (operationSpec: unknown, variantKey?: string) => OperationHttpDoc;
|
|
176
218
|
//# sourceMappingURL=spec-to-operation-doc.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-to-operation-doc.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"spec-to-operation-doc.d.ts","sourceRoot":"","sources":["../../../src/companion/spec-to-operation-doc.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* - **Tier 2** `injectFieldDocsIntoJsonSchema` — per-field `meaning` /
|
|
11
11
|
* `whyItMatters` / `relationshipContext` / enum-value meanings → property
|
|
12
12
|
* `description` + `x-enum-descriptions` on a request/response JSON-Schema
|
|
13
|
-
* fragment
|
|
13
|
+
* fragment; `injectFieldDocsIntoCollectionContract` applies the same to a
|
|
14
|
+
* paginated collection's `filters` bag and `data[]` items.
|
|
14
15
|
*
|
|
15
16
|
* See `.claude/plans/technical-doc-openapi-spec-integration.md`. Without authored
|
|
16
17
|
* spec prose the description is empty and the operation falls back to the
|
|
@@ -180,11 +181,36 @@ const composeFieldDescription = (doc) => {
|
|
|
180
181
|
* Joins by EXACT property-name match — DTO property names that diverge from
|
|
181
182
|
* the resource's field names (renamed / computed / backend-stripped fields)
|
|
182
183
|
* are simply left undocumented rather than mis-documented.
|
|
184
|
+
*
|
|
185
|
+
* "Top level" includes each branch of a top-level `oneOf` / `anyOf` / `allOf`.
|
|
186
|
+
* A polymorphic resource's representation is a union whose branches carry the
|
|
187
|
+
* properties themselves — the fragment has no `properties` of its own — and
|
|
188
|
+
* every branch's properties are still the resource's own top-level fields. Only
|
|
189
|
+
* composition keywords are entered, never an object property, so the rule above
|
|
190
|
+
* still holds. Without this, 42 of the 58 properties of Wonder Todos' `todos`
|
|
191
|
+
* read and list representations (`title`, `status`, `priority`, …) carried no
|
|
192
|
+
* description.
|
|
193
|
+
*
|
|
194
|
+
* A paginated collection re-wraps those fields one level down; see
|
|
195
|
+
* `injectFieldDocsIntoCollectionContract` for the two containers it adds.
|
|
183
196
|
*/
|
|
184
197
|
export const injectFieldDocsIntoJsonSchema = (fragment, fieldDocsByName) => {
|
|
185
198
|
if (!isPlainObject(fragment)) {
|
|
186
199
|
return;
|
|
187
200
|
}
|
|
201
|
+
// A body that is a LIST of rows (a bulk create or update answers one row per item, #1872) documents its rows.
|
|
202
|
+
if (fragment['type'] === 'array' && isPlainObject(fragment['items'])) {
|
|
203
|
+
injectFieldDocsIntoJsonSchema(fragment['items'], fieldDocsByName);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
for (const compositionKeyword of ['oneOf', 'anyOf', 'allOf']) {
|
|
207
|
+
const branches = fragment[compositionKeyword];
|
|
208
|
+
if (Array.isArray(branches)) {
|
|
209
|
+
for (const branch of branches) {
|
|
210
|
+
injectFieldDocsIntoJsonSchema(branch, fieldDocsByName);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
188
214
|
const properties = fragment['properties'];
|
|
189
215
|
if (!isPlainObject(properties)) {
|
|
190
216
|
return;
|
|
@@ -211,14 +237,100 @@ export const injectFieldDocsIntoJsonSchema = (fragment, fieldDocsByName) => {
|
|
|
211
237
|
}
|
|
212
238
|
}
|
|
213
239
|
};
|
|
240
|
+
/**
|
|
241
|
+
* Enrich the two places a paginated collection contract carries the resource's OWN fields one
|
|
242
|
+
* level down, where `injectFieldDocsIntoJsonSchema` (top level only) cannot reach them:
|
|
243
|
+
*
|
|
244
|
+
* - the request's `filters` object — one property per filterable field, which the generator
|
|
245
|
+
* flattens into query parameters (`?status=…`), copying each property's `description`;
|
|
246
|
+
* - the response envelope's `data[]` items — the resource rows a LIST / SEARCH returns.
|
|
247
|
+
*
|
|
248
|
+
* This is not the general nested walk `injectFieldDocsIntoJsonSchema` declines: a nested object's
|
|
249
|
+
* properties have no field specification, while these two containers hold the resource's own
|
|
250
|
+
* top-level fields, re-wrapped by the framework's collection contract. Before this, 59% of the
|
|
251
|
+
* list-item properties and 219 query filters in the Wonder Todos document carried no description,
|
|
252
|
+
* although the same fields were fully described in the read and create responses.
|
|
253
|
+
*
|
|
254
|
+
* Call it only for a paginated collection operation (LIST, or SEARCH-like). Anything else passes
|
|
255
|
+
* through unchanged, because neither container exists.
|
|
256
|
+
*/
|
|
257
|
+
export const injectFieldDocsIntoCollectionContract = (requestBodySchema, responseBodySchema, fieldDocsByName) => {
|
|
258
|
+
const filters = isPlainObject(requestBodySchema) && isPlainObject(requestBodySchema['properties'])
|
|
259
|
+
? requestBodySchema['properties']['filters']
|
|
260
|
+
: undefined;
|
|
261
|
+
injectFieldDocsIntoJsonSchema(filters, fieldDocsByName);
|
|
262
|
+
const data = isPlainObject(responseBodySchema) && isPlainObject(responseBodySchema['properties'])
|
|
263
|
+
? responseBodySchema['properties']['data']
|
|
264
|
+
: undefined;
|
|
265
|
+
const items = isPlainObject(data) ? data['items'] : undefined;
|
|
266
|
+
injectFieldDocsIntoJsonSchema(items, fieldDocsByName);
|
|
267
|
+
injectNestedFilterDescriptionsFromRows(filters, items);
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* A filter on a nested field is keyed by its dotted path (`linkedResource.resourceType`, #1630), so it
|
|
271
|
+
* matches no field specification by name and was published with no description. The field it filters
|
|
272
|
+
* is described where it is declared — in the row schema the same collection returns — so the filter
|
|
273
|
+
* takes that description, found by walking the row along the path. Only a filter that has none of its
|
|
274
|
+
* own is filled in, and a path the rows do not carry (or reach only through a `$ref`) is left as is.
|
|
275
|
+
*/
|
|
276
|
+
const injectNestedFilterDescriptionsFromRows = (filters, rowSchema) => {
|
|
277
|
+
if (!isPlainObject(filters) || !isPlainObject(filters['properties'])) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
for (const [filterName, filterSchema] of Object.entries(filters['properties'])) {
|
|
281
|
+
if (!filterName.includes('.') || !isPlainObject(filterSchema) || filterSchema['description'] !== undefined) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const description = describedPropertyAtPath(rowSchema, filterName.split('.'));
|
|
285
|
+
if (description !== undefined) {
|
|
286
|
+
filterSchema['description'] = description;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* The description of the property `path` names inside `schema`, entering `oneOf` / `anyOf` / `allOf`
|
|
292
|
+
* branches at each step — a nullable object is `anyOf [object, null]` — and taking the first branch
|
|
293
|
+
* that has the property.
|
|
294
|
+
*/
|
|
295
|
+
const describedPropertyAtPath = (schema, path) => {
|
|
296
|
+
if (!isPlainObject(schema) || path.length === 0) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
const [head, ...rest] = path;
|
|
300
|
+
const properties = schema['properties'];
|
|
301
|
+
if (isPlainObject(properties) && isPlainObject(properties[head])) {
|
|
302
|
+
const property = properties[head];
|
|
303
|
+
if (rest.length === 0) {
|
|
304
|
+
return typeof property['description'] === 'string' ? property['description'] : undefined;
|
|
305
|
+
}
|
|
306
|
+
const found = describedPropertyAtPath(property, rest);
|
|
307
|
+
if (found !== undefined) {
|
|
308
|
+
return found;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
for (const compositionKeyword of ['oneOf', 'anyOf', 'allOf']) {
|
|
312
|
+
const branches = schema[compositionKeyword];
|
|
313
|
+
if (!Array.isArray(branches)) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
for (const branch of branches) {
|
|
317
|
+
const found = describedPropertyAtPath(branch, path);
|
|
318
|
+
if (found !== undefined) {
|
|
319
|
+
return found;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return undefined;
|
|
324
|
+
};
|
|
214
325
|
const asNonEmptyString = (value) => typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
215
326
|
/**
|
|
216
327
|
* Like `asNonEmptyString`, but for PROSE fields surfaced verbatim to API
|
|
217
328
|
* consumers (response-status `meaning`, error-scenario `when`, example `title`,
|
|
218
329
|
* `rateLimitNote`): additionally strips implementation-only noise (see
|
|
219
330
|
* `stripImplementationNoise`) and returns `undefined` if the value is empty
|
|
220
|
-
* before OR after cleaning. Do NOT use for code-like fields (`code`,
|
|
221
|
-
* `errorCode`, `forStatus`) — those pass through untouched via
|
|
331
|
+
* before OR after cleaning. Do NOT use for code-like fields (`code`, `errorType`,
|
|
332
|
+
* `customMessageReference`, `errorCode`, `forStatus`) — those pass through untouched via
|
|
333
|
+
* `asNonEmptyString`.
|
|
222
334
|
*/
|
|
223
335
|
const asCleanProse = (value) => {
|
|
224
336
|
const raw = asNonEmptyString(value);
|
|
@@ -239,10 +351,10 @@ const asCleanProse = (value) => {
|
|
|
239
351
|
*
|
|
240
352
|
* Prose fields (`meaning` / `when` / `title` / `rateLimitNote`) are cleaned of
|
|
241
353
|
* implementation-only noise via `asCleanProse`, consistent with the Tier-1
|
|
242
|
-
* `description` and Tier-2 field descriptions. `code` / `forStatus`
|
|
243
|
-
* `
|
|
244
|
-
*
|
|
245
|
-
*
|
|
354
|
+
* `description` and Tier-2 field descriptions. `code` / `forStatus` are
|
|
355
|
+
* `HttpResponseStatusCode` values whose runtime string (`'200'`, …) is the OpenAPI
|
|
356
|
+
* `responses` key; `errorType` / `customMessageReference` / `errorCode` are the
|
|
357
|
+
* error-body wire values a client branches on. All pass through untouched.
|
|
246
358
|
*/
|
|
247
359
|
export const buildOperationHttpDocFromSpec = (operationSpec, variantKey) => {
|
|
248
360
|
if (!isPlainObject(operationSpec)) {
|
|
@@ -274,6 +386,12 @@ export const buildOperationHttpDocFromSpec = (operationSpec, variantKey) => {
|
|
|
274
386
|
if (code === undefined || when === undefined)
|
|
275
387
|
return undefined;
|
|
276
388
|
const scenario = { code, when };
|
|
389
|
+
const errorType = asNonEmptyString(entry['errorType']);
|
|
390
|
+
if (errorType !== undefined)
|
|
391
|
+
scenario.errorType = errorType;
|
|
392
|
+
const customMessageReference = asNonEmptyString(entry['customMessageReference']);
|
|
393
|
+
if (customMessageReference !== undefined)
|
|
394
|
+
scenario.customMessageReference = customMessageReference;
|
|
277
395
|
const errorCode = asNonEmptyString(entry['errorCode']);
|
|
278
396
|
if (errorCode !== undefined)
|
|
279
397
|
scenario.errorCode = errorCode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-to-operation-doc.js","sourceRoot":"","sources":["../../../../src/companion/spec-to-operation-doc.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @wildo-package @wildo-ai/saas-technical-doc/companion (spec → OpenAPI enrichment)\n *\n * Pure mappers from a resource SPECIFICATION's authored prose into OpenAPI:\n * - **Tier 1** `buildOperationDocFromSpec` — operation `purpose` / `outcome` /\n * `whenToUse` (with per-variant overrides) → operation `description` on an\n * `OperationProjection`. The `summary` (operation TITLE) is intentionally NOT\n * produced here: it is a short verb-first label the generator derives\n * (`buildDefaultSummary`), kept separate from the authored prose.\n * - **Tier 2** `injectFieldDocsIntoJsonSchema` — per-field `meaning` /\n * `whyItMatters` / `relationshipContext` / enum-value meanings → property\n * `description` + `x-enum-descriptions` on a request/response JSON-Schema\n * fragment.\n *\n * See `.claude/plans/technical-doc-openapi-spec-integration.md`. Without authored\n * spec prose the description is empty and the operation falls back to the\n * generator's humanized verb-first title alone (e.g. `\"List users\"`) with no\n * field documentation — the \"quality will be very poor\" failure mode this\n * integration removes.\n *\n * @wildo-boundary\n * Imports NOTHING — pure string composition. It deliberately declares its\n * own NARROW structural input types instead of importing\n * `ResourceOperationSpecification` / `ResourceOperationVariantSpecification`\n * from `@wildo-ai/saas-specifications`. Same K-3 boundary reasoning the rest\n * of `companion/` follows (see `operation-projection.schemas.ts`): pulling\n * the spec package would drag a heavy type graph into the decorator-free\n * technical-doc companion bundle. The types below MUST remain a structural\n * SUBSET of the authored spec types — only the prose fields this mapper\n * reads. If the spec layer renames a prose field, update these in lockstep.\n */\n\n/**\n * Narrow structural view of a per-variant operation spec — the prose fields\n * a variant may override. Subset of `ResourceOperationVariantSpecification`.\n */\nexport interface OperationSpecVariantProse {\n purpose?: string;\n outcome?: string;\n whenToUse?: string;\n /** Complete OpenAPI example replacement for this response-shape variant. */\n examples?: Array<{ title: string; request?: unknown; response?: unknown; forStatus?: string }>;\n}\n\n/**\n * Narrow structural view of an operation spec — the base prose plus the\n * per-variant overrides map. Subset of `ResourceOperationSpecification`.\n * `variants` is keyed by the named variant key, with the reserved `'default'`\n * key for the no-`variantKey` (default-variant) path.\n */\nexport interface OperationSpecProse {\n purpose?: string;\n outcome?: string;\n whenToUse?: string;\n variants?: Record<string, OperationSpecVariantProse | undefined>;\n}\n\n/** The OpenAPI prose this mapper produces. Both fields optional. */\nexport interface OperationDoc {\n summary?: string;\n description?: string;\n}\n\n/** OperationProjection description cap: ≤2000 (Zod-enforced downstream). The\n * summary (title) is derived by the generator, not built here. */\nconst DESCRIPTION_MAX_LENGTH = 2000;\n\n/** Collapse all whitespace runs to single spaces and trim (single-line summary). */\nconst toSingleLine = (value: string): string => value.replace(/\\s+/gu, ' ').trim();\n\n/** Clamp to `max` chars, appending an ellipsis when truncated. */\nconst clampLength = (value: string, max: number): string =>\n value.length <= max ? value : `${value.slice(0, max - 1).trimEnd()}…`;\n\n/**\n * Strip implementation-only noise that authored spec prose carries for the\n * FRAMEWORK-KNOWLEDGE audience but that means nothing to an API consumer\n * reading the generated docs:\n * - Parentheticals naming a runtime variant — `(API_CALL in factory)`,\n * `(REPOSITORY_ONLY create in factory — …)`.\n * - Dangling `in factory` / `in the factory` phrases.\n * Then normalise the leftover spacing/punctuation. Conservative by design — it\n * only removes parentheticals that actually contain a variant marker, so\n * ordinary parenthetical prose survives.\n *\n * This is the single canonical \"spec prose → consumer prose\" cleaner, applied\n * to EVERY prose surface that reaches the OpenAPI output: the Tier-1 operation\n * `description` (here), Tier-2 field descriptions + `x-enum-descriptions`\n * (`composeFieldDescription` / `cleanEnumMeanings`), Tier-3 response/error/\n * example/rate-limit prose (`asCleanProse`), and the resource `tags[].description`\n * (applied by the generator — `openapi-generator.ts` imports this). Exported so\n * those out-of-module surfaces clean prose identically rather than diverging.\n */\nexport const stripImplementationNoise = (value: string): string =>\n value\n .replace(\n /\\s*\\([^()]*\\b(?:API_CALL_WITH_CALLBACK|API_CALL|REPOSITORY_ONLY|INTERNAL_CALL|CRON_JOB|BATCH_JOB)\\b[^()]*\\)/gu,\n '',\n )\n .replace(/\\s+in\\s+(?:the\\s+)?factory\\b/giu, '')\n .replace(/\\(\\s*\\)/gu, '')\n .replace(/\\s+([.,;:])/gu, '$1')\n .replace(/\\s{2,}/gu, ' ')\n .trim();\n\n/**\n * Resolve the EFFECTIVE prose for an operation, applying variant overlay\n * semantics: a present variant field REPLACES the base field; an absent\n * variant field falls back to the base. `variantKey === undefined` resolves\n * the reserved `'default'` variant.\n *\n * Returns `{}` when the spec is absent or carries no prose at all — callers\n * leave `OperationProjection.summary` / `.description` unset so the\n * generator's humanized fallback applies (graceful degradation for\n * operations / resources with no authored spec).\n */\nexport const buildOperationDocFromSpec = (\n operationSpec: OperationSpecProse | undefined,\n variantKey: string | undefined,\n): OperationDoc => {\n if (operationSpec === undefined) {\n return {};\n }\n\n const variant = operationSpec.variants?.[variantKey ?? 'default'];\n const effectivePurpose = variant?.purpose ?? operationSpec.purpose;\n const effectiveOutcome = variant?.outcome ?? operationSpec.outcome;\n const effectiveWhenToUse = variant?.whenToUse ?? operationSpec.whenToUse;\n\n const doc: OperationDoc = {};\n\n // The OpenAPI `summary` (operation TITLE / nav label / breadcrumb) is\n // intentionally NOT taken from `purpose`. `purpose` is impl-aware intent prose\n // authored for the framework-knowledge layer — a full sentence, often with\n // runtime detail like \"(API_CALL in factory)\" — which is far too long and too\n // internal to be a title. The generator derives a short verb-first title\n // (`buildDefaultSummary`); here we only build the DESCRIPTION from the authored\n // prose. The description LEADS with `purpose` (the intent), then the observable\n // `outcome`, then a \"When to use\" clause — each cleaned of implementation noise.\n const descriptionParts: string[] = [];\n if (effectivePurpose !== undefined) {\n const purpose = stripImplementationNoise(toSingleLine(effectivePurpose));\n if (purpose.length > 0) descriptionParts.push(purpose);\n }\n if (effectiveOutcome !== undefined) {\n const outcome = stripImplementationNoise(effectiveOutcome.trim());\n if (outcome.length > 0) descriptionParts.push(outcome);\n }\n if (effectiveWhenToUse !== undefined) {\n const whenToUse = stripImplementationNoise(effectiveWhenToUse.trim());\n if (whenToUse.length > 0) descriptionParts.push(`**When to use:** ${whenToUse}`);\n }\n if (descriptionParts.length > 0) {\n doc.description = clampLength(descriptionParts.join('\\n\\n'), DESCRIPTION_MAX_LENGTH);\n }\n\n return doc;\n};\n\n// ---------------------------------------------------------------------------\n// Tier 2 — field / enum documentation\n// ---------------------------------------------------------------------------\n\n/**\n * Narrow structural view of one field's authored documentation. Built by the\n * companion projector from the extracted resource field specs and consumed by\n * `injectFieldDocsIntoJsonSchema`. Boundary-clean (no `@wildo-ai/saas-specifications`\n * import): the projector maps `ExtractedFieldSpec.params.{meaning,whyItMatters,\n * relationshipContext,values}` into this shape before calling the injector.\n */\nexport interface FieldDoc {\n /** Business meaning of the field (becomes the lead of the property description). */\n meaning?: string;\n /** Why the field is included (appended to the description). */\n whyItMatters?: string;\n /** For foreign keys: the relationship this field expresses. */\n relationshipContext?: string;\n /** For enum fields: enum value string → authored meaning. */\n enumValueMeanings?: Record<string, string>;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Clean an enum value→meaning record for consumer-facing output: strip\n * implementation-only noise from each meaning (see `stripImplementationNoise`)\n * and drop any entry that is non-string or empty after cleaning. Used for both\n * the human-readable \"Values:\" legend and the machine `x-enum-descriptions`\n * extension so the two never diverge.\n */\nconst cleanEnumMeanings = (enumValueMeanings: Record<string, string>): Record<string, string> => {\n const cleaned: Record<string, string> = {};\n for (const [value, meaning] of Object.entries(enumValueMeanings)) {\n if (typeof meaning !== 'string') {\n continue;\n }\n const cleanedMeaning = stripImplementationNoise(meaning.trim());\n if (cleanedMeaning.length > 0) {\n cleaned[value] = cleanedMeaning;\n }\n }\n return cleaned;\n};\n\n/**\n * Compose a single property `description` from a field's authored docs:\n * meaning + whyItMatters + relationshipContext as space-joined sentences,\n * then an optional markdown \"Values:\" legend from enum meanings. Each authored\n * sentence is run through `stripImplementationNoise` — the field-spec prose is\n * authored for the framework-knowledge audience and may carry runtime markers\n * (`(API_CALL in factory)`) that mean nothing to an API consumer. Returns\n * `undefined` when the field carries no usable prose.\n */\nconst composeFieldDescription = (doc: FieldDoc): string | undefined => {\n const sentences: string[] = [];\n for (const candidate of [doc.meaning, doc.whyItMatters, doc.relationshipContext]) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n const cleaned = stripImplementationNoise(candidate.trim());\n if (cleaned.length > 0) {\n sentences.push(cleaned);\n }\n }\n }\n let description = sentences.join(' ');\n\n if (doc.enumValueMeanings !== undefined) {\n const legend = Object.entries(cleanEnumMeanings(doc.enumValueMeanings)).map(\n ([value, meaning]) => `- \\`${value}\\`: ${meaning}`,\n );\n if (legend.length > 0) {\n const block = `Values:\\n${legend.join('\\n')}`;\n description = description.length > 0 ? `${description}\\n\\n${block}` : block;\n }\n }\n\n return description.length > 0 ? description : undefined;\n};\n\n/**\n * Enrich the TOP-LEVEL properties of an OpenAPI/JSON-Schema object fragment\n * (a `requestBodySchema` / `responseBodySchema` produced by\n * `convertZodSchemaToOpenApiSchema`) with authored field documentation.\n * Mutates `fragment` in place.\n *\n * Rules:\n * - Property `description` is composed from the field's docs ONLY when the\n * property has no existing `description` — a Zod `.describe()` authored on\n * the DTO field wins (it is closer to the wire contract).\n * - `x-enum-descriptions` (value → meaning) is set whenever enum meanings\n * exist, independent of the description-clobber rule, for machine consumers.\n *\n * Only top-level properties are walked: the field-spec extractor produces\n * specs for top-level schema fields only, so nested-object properties have no\n * authored docs to apply. No-op for non-object fragments (`null`, scalars).\n * Joins by EXACT property-name match — DTO property names that diverge from\n * the resource's field names (renamed / computed / backend-stripped fields)\n * are simply left undocumented rather than mis-documented.\n */\nexport const injectFieldDocsIntoJsonSchema = (\n fragment: unknown,\n fieldDocsByName: Record<string, FieldDoc>,\n): void => {\n if (!isPlainObject(fragment)) {\n return;\n }\n const properties = fragment['properties'];\n if (!isPlainObject(properties)) {\n return;\n }\n for (const [propertyName, rawPropertySchema] of Object.entries(properties)) {\n if (!isPlainObject(rawPropertySchema)) {\n continue;\n }\n const doc = fieldDocsByName[propertyName];\n if (doc === undefined) {\n continue;\n }\n if (rawPropertySchema['description'] === undefined) {\n const description = composeFieldDescription(doc);\n if (description !== undefined) {\n rawPropertySchema['description'] = description;\n }\n }\n if (doc.enumValueMeanings !== undefined) {\n const cleanedEnumMeanings = cleanEnumMeanings(doc.enumValueMeanings);\n if (Object.keys(cleanedEnumMeanings).length > 0) {\n rawPropertySchema['x-enum-descriptions'] = cleanedEnumMeanings;\n }\n }\n }\n};\n\n// ---------------------------------------------------------------------------\n// Tier 3 — operation HTTP documentation (response statuses / errors / examples)\n// ---------------------------------------------------------------------------\n\n/**\n * Projection-shaped HTTP documentation for one operation (Tier 3). Mirrors the\n * authored `ResourceOperationSpecification` HTTP fields, normalized to plain\n * JSON the OpenAPI generator emits as `responses` / `examples` / extensions.\n */\nexport interface OperationHttpDoc {\n responseStatuses?: Array<{ code: string; meaning: string }>;\n errorScenarios?: Array<{ code: string; when: string; errorCode?: string }>;\n idempotent?: boolean;\n rateLimitNote?: string;\n examples?: Array<{ title: string; request?: unknown; response?: unknown; forStatus?: string }>;\n}\n\nconst asNonEmptyString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n\n/**\n * Like `asNonEmptyString`, but for PROSE fields surfaced verbatim to API\n * consumers (response-status `meaning`, error-scenario `when`, example `title`,\n * `rateLimitNote`): additionally strips implementation-only noise (see\n * `stripImplementationNoise`) and returns `undefined` if the value is empty\n * before OR after cleaning. Do NOT use for code-like fields (`code`,\n * `errorCode`, `forStatus`) — those pass through untouched via `asNonEmptyString`.\n */\nconst asCleanProse = (value: unknown): string | undefined => {\n const raw = asNonEmptyString(value);\n if (raw === undefined) {\n return undefined;\n }\n const cleaned = stripImplementationNoise(raw);\n return cleaned.length > 0 ? cleaned : undefined;\n};\n\n/**\n * Extract + normalize the Tier-3 HTTP-documentation fields from a raw authored\n * operation spec into the projection shape. Variant examples are a complete\n * overlay: when `variants.<key>.examples` is present it replaces the base\n * operation examples, rather than merging a payload that may target a different\n * response schema. Defensive: a malformed entry is dropped rather than\n * poisoning the whole projection (the generator re-validates via Zod). Returns\n * `{}` when the operation authored no HTTP docs.\n *\n * Prose fields (`meaning` / `when` / `title` / `rateLimitNote`) are cleaned of\n * implementation-only noise via `asCleanProse`, consistent with the Tier-1\n * `description` and Tier-2 field descriptions. `code` / `forStatus` /\n * `errorCode` are `HttpResponseStatusCode` / error-code enum values whose\n * runtime string value (`'200'`, …) is the OpenAPI `responses` key / a machine\n * code, so they pass through untouched as strings.\n */\nexport const buildOperationHttpDocFromSpec = (operationSpec: unknown, variantKey?: string): OperationHttpDoc => {\n if (!isPlainObject(operationSpec)) {\n return {};\n }\n const doc: OperationHttpDoc = {};\n\n const responseStatuses = operationSpec['responseStatuses'];\n if (Array.isArray(responseStatuses)) {\n const normalized = responseStatuses\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const code = asNonEmptyString(entry['code']);\n const meaning = asCleanProse(entry['meaning']);\n return code !== undefined && meaning !== undefined ? { code, meaning } : undefined;\n })\n .filter((entry): entry is { code: string; meaning: string } => entry !== undefined);\n if (normalized.length > 0) doc.responseStatuses = normalized;\n }\n\n const errorScenarios = operationSpec['errorScenarios'];\n if (Array.isArray(errorScenarios)) {\n const normalized = errorScenarios\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const code = asNonEmptyString(entry['code']);\n const when = asCleanProse(entry['when']);\n if (code === undefined || when === undefined) return undefined;\n const scenario: { code: string; when: string; errorCode?: string } = { code, when };\n const errorCode = asNonEmptyString(entry['errorCode']);\n if (errorCode !== undefined) scenario.errorCode = errorCode;\n return scenario;\n })\n .filter((entry): entry is { code: string; when: string; errorCode?: string } => entry !== undefined);\n if (normalized.length > 0) doc.errorScenarios = normalized;\n }\n\n if (typeof operationSpec['idempotent'] === 'boolean') {\n doc.idempotent = operationSpec['idempotent'];\n }\n\n const rateLimitNote = asCleanProse(operationSpec['rateLimitNote']);\n if (rateLimitNote !== undefined) {\n doc.rateLimitNote = rateLimitNote;\n }\n\n const variants = operationSpec['variants'];\n const variant = isPlainObject(variants) ? variants[variantKey ?? 'default'] : undefined;\n // A present variant `examples` member deliberately suppresses the base even\n // when it is malformed or empty: falling back would publish a payload under a\n // schema the variant does not own. The normalizer below emits no example for\n // that invalid/empty override, which is safer than a misleading one.\n const examples =\n isPlainObject(variant) && Object.prototype.hasOwnProperty.call(variant, 'examples')\n ? variant['examples']\n : operationSpec['examples'];\n if (Array.isArray(examples)) {\n const normalized = examples\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const title = asCleanProse(entry['title']);\n if (title === undefined) return undefined;\n const example: { title: string; request?: unknown; response?: unknown; forStatus?: string } = { title };\n if (entry['request'] !== undefined) example.request = entry['request'];\n if (entry['response'] !== undefined) example.response = entry['response'];\n const forStatus = asNonEmptyString(entry['forStatus']);\n if (forStatus !== undefined) example.forStatus = forStatus;\n return example;\n })\n .filter(\n (entry): entry is { title: string; request?: unknown; response?: unknown; forStatus?: string } =>\n entry !== undefined,\n );\n if (normalized.length > 0) doc.examples = normalized;\n }\n\n return doc;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"spec-to-operation-doc.js","sourceRoot":"","sources":["../../../src/companion/spec-to-operation-doc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAiCH;kEACkE;AAClE,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,oFAAoF;AACpF,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAEnF,kEAAkE;AAClE,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,GAAW,EAAU,EAAE,CACzD,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AAExE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAU,EAAE,CAChE,KAAK;KACF,OAAO,CACN,+GAA+G,EAC/G,EAAE,CACH;KACA,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC;KAC9C,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;KACxB,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC;KAC9B,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;KACxB,IAAI,EAAE,CAAC;AAEZ;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,aAA6C,EAC7C,UAA8B,EAChB,EAAE;IAChB,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,OAAO,EAAE,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC;IACnE,MAAM,gBAAgB,GAAG,OAAO,EAAE,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC;IACnE,MAAM,kBAAkB,GAAG,OAAO,EAAE,SAAS,IAAI,aAAa,CAAC,SAAS,CAAC;IAEzE,MAAM,GAAG,GAAiB,EAAE,CAAC;IAE7B,sEAAsE;IACtE,+EAA+E;IAC/E,2EAA2E;IAC3E,8EAA8E;IAC9E,yEAAyE;IACzE,gFAAgF;IAChF,gFAAgF;IAChF,iFAAiF;IACjF,MAAM,gBAAgB,GAAa,EAAE,CAAC;IACtC,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,wBAAwB,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACzE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,wBAAwB,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAwBF,MAAM,aAAa,GAAG,CAAC,KAAc,EAAoC,EAAE,CACzE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,CAAC,iBAAyC,EAA0B,EAAE;IAC9F,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACjE,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QACD,MAAM,cAAc,GAAG,wBAAwB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,uBAAuB,GAAG,CAAC,GAAa,EAAsB,EAAE;IACpE,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACjF,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,GAAG,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CACzE,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,KAAK,OAAO,OAAO,EAAE,CACnD,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,WAAW,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,QAAiB,EACjB,eAAyC,EACnC,EAAE;IACR,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IACD,8GAA8G;IAC9G,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,OAAO,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACrE,6BAA6B,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IACD,KAAK,MAAM,kBAAkB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QACtE,MAAM,QAAQ,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,6BAA6B,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC1C,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,YAAY,EAAE,iBAAiB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QACD,IAAI,iBAAiB,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;YACnD,MAAM,WAAW,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;YACjD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,iBAAiB,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;YACjD,CAAC;QACH,CAAC;QACD,IAAI,GAAG,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YACrE,IAAI,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,iBAAiB,CAAC,qBAAqB,CAAC,GAAG,mBAAmB,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CACnD,iBAA0B,EAC1B,kBAA2B,EAC3B,eAAyC,EACnC,EAAE;IACR,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC,IAAI,aAAa,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAChG,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC;QAC5C,CAAC,CAAC,SAAS,CAAC;IACd,6BAA6B,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,aAAa,CAAC,kBAAkB,CAAC,IAAI,aAAa,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC/F,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;QAC1C,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,6BAA6B,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;IACtD,sCAAsC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,sCAAsC,GAAG,CAAC,OAAgB,EAAE,SAAkB,EAAQ,EAAE;IAC5F,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC/E,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3G,SAAS;QACX,CAAC;QACD,MAAM,WAAW,GAAG,uBAAuB,CAAC,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,YAAY,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,CAAC,MAAe,EAAE,IAAuB,EAAsB,EAAE;IAC/F,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IACxC,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,IAAK,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAK,CAA4B,CAAC;QAC9D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,OAAO,QAAQ,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,CAAC;QACD,MAAM,KAAK,GAAG,uBAAuB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,KAAK,MAAM,kBAAkB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QACtE,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAmCF,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAsB,EAAE,CAC9D,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAElF;;;;;;;;GAQG;AACH,MAAM,YAAY,GAAG,CAAC,KAAc,EAAsB,EAAE;IAC1D,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,aAAsB,EAAE,UAAmB,EAAoB,EAAE;IAC7G,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAqB,EAAE,CAAC;IAEjC,MAAM,gBAAgB,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,gBAAgB;aAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC5C,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC/C,OAAO,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,KAAK,EAA8C,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QACtF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,gBAAgB,GAAG,UAAU,CAAC;IAC/D,CAAC;IAED,MAAM,cAAc,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,cAAc;aAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC5C,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC/D,MAAM,QAAQ,GAA8B,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;YACvD,IAAI,SAAS,KAAK,SAAS;gBAAE,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;YAC5D,MAAM,sBAAsB,GAAG,gBAAgB,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACjF,IAAI,sBAAsB,KAAK,SAAS;gBAAE,QAAQ,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;YACnG,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;YACvD,IAAI,SAAS,KAAK,SAAS;gBAAE,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;YAC5D,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,KAAK,EAAsC,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QAC9E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC;IAC7D,CAAC;IAED,IAAI,OAAO,aAAa,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;QACrD,GAAG,CAAC,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;IACnE,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,GAAG,CAAC,aAAa,GAAG,aAAa,CAAC;IACpC,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,4EAA4E;IAC5E,8EAA8E;IAC9E,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,QAAQ,GACZ,aAAa,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC;QACjF,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACrB,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,QAAQ;aACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3C,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC1C,MAAM,OAAO,GAAiF,EAAE,KAAK,EAAE,CAAC;YACxG,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YACvE,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;YAC1E,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;YACvD,IAAI,SAAS,KAAK,SAAS;gBAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3D,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;aACD,MAAM,CACL,CAAC,KAAK,EAAyF,EAAE,CAC/F,KAAK,KAAK,SAAS,CACtB,CAAC;QACJ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC;IACvD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC","sourcesContent":["/**\n * @wildo-package @wildo-ai/saas-technical-doc/companion (spec → OpenAPI enrichment)\n *\n * Pure mappers from a resource SPECIFICATION's authored prose into OpenAPI:\n * - **Tier 1** `buildOperationDocFromSpec` — operation `purpose` / `outcome` /\n * `whenToUse` (with per-variant overrides) → operation `description` on an\n * `OperationProjection`. The `summary` (operation TITLE) is intentionally NOT\n * produced here: it is a short verb-first label the generator derives\n * (`buildDefaultSummary`), kept separate from the authored prose.\n * - **Tier 2** `injectFieldDocsIntoJsonSchema` — per-field `meaning` /\n * `whyItMatters` / `relationshipContext` / enum-value meanings → property\n * `description` + `x-enum-descriptions` on a request/response JSON-Schema\n * fragment; `injectFieldDocsIntoCollectionContract` applies the same to a\n * paginated collection's `filters` bag and `data[]` items.\n *\n * See `.claude/plans/technical-doc-openapi-spec-integration.md`. Without authored\n * spec prose the description is empty and the operation falls back to the\n * generator's humanized verb-first title alone (e.g. `\"List users\"`) with no\n * field documentation — the \"quality will be very poor\" failure mode this\n * integration removes.\n *\n * @wildo-boundary\n * Imports NOTHING — pure string composition. It deliberately declares its\n * own NARROW structural input types instead of importing\n * `ResourceOperationSpecification` / `ResourceOperationVariantSpecification`\n * from `@wildo-ai/saas-specifications`. Same K-3 boundary reasoning the rest\n * of `companion/` follows (see `operation-projection.schemas.ts`): pulling\n * the spec package would drag a heavy type graph into the decorator-free\n * technical-doc companion bundle. The types below MUST remain a structural\n * SUBSET of the authored spec types — only the prose fields this mapper\n * reads. If the spec layer renames a prose field, update these in lockstep.\n */\n\n/**\n * Narrow structural view of a per-variant operation spec — the prose fields\n * a variant may override. Subset of `ResourceOperationVariantSpecification`.\n */\nexport interface OperationSpecVariantProse {\n purpose?: string;\n outcome?: string;\n whenToUse?: string;\n /** Complete OpenAPI example replacement for this response-shape variant. */\n examples?: Array<{ title: string; request?: unknown; response?: unknown; forStatus?: string }>;\n}\n\n/**\n * Narrow structural view of an operation spec — the base prose plus the\n * per-variant overrides map. Subset of `ResourceOperationSpecification`.\n * `variants` is keyed by the named variant key, with the reserved `'default'`\n * key for the no-`variantKey` (default-variant) path.\n */\nexport interface OperationSpecProse {\n purpose?: string;\n outcome?: string;\n whenToUse?: string;\n variants?: Record<string, OperationSpecVariantProse | undefined>;\n}\n\n/** The OpenAPI prose this mapper produces. Both fields optional. */\nexport interface OperationDoc {\n summary?: string;\n description?: string;\n}\n\n/** OperationProjection description cap: ≤2000 (Zod-enforced downstream). The\n * summary (title) is derived by the generator, not built here. */\nconst DESCRIPTION_MAX_LENGTH = 2000;\n\n/** Collapse all whitespace runs to single spaces and trim (single-line summary). */\nconst toSingleLine = (value: string): string => value.replace(/\\s+/gu, ' ').trim();\n\n/** Clamp to `max` chars, appending an ellipsis when truncated. */\nconst clampLength = (value: string, max: number): string =>\n value.length <= max ? value : `${value.slice(0, max - 1).trimEnd()}…`;\n\n/**\n * Strip implementation-only noise that authored spec prose carries for the\n * FRAMEWORK-KNOWLEDGE audience but that means nothing to an API consumer\n * reading the generated docs:\n * - Parentheticals naming a runtime variant — `(API_CALL in factory)`,\n * `(REPOSITORY_ONLY create in factory — …)`.\n * - Dangling `in factory` / `in the factory` phrases.\n * Then normalise the leftover spacing/punctuation. Conservative by design — it\n * only removes parentheticals that actually contain a variant marker, so\n * ordinary parenthetical prose survives.\n *\n * This is the single canonical \"spec prose → consumer prose\" cleaner, applied\n * to EVERY prose surface that reaches the OpenAPI output: the Tier-1 operation\n * `description` (here), Tier-2 field descriptions + `x-enum-descriptions`\n * (`composeFieldDescription` / `cleanEnumMeanings`), Tier-3 response/error/\n * example/rate-limit prose (`asCleanProse`), and the resource `tags[].description`\n * (applied by the generator — `openapi-generator.ts` imports this). Exported so\n * those out-of-module surfaces clean prose identically rather than diverging.\n */\nexport const stripImplementationNoise = (value: string): string =>\n value\n .replace(\n /\\s*\\([^()]*\\b(?:API_CALL_WITH_CALLBACK|API_CALL|REPOSITORY_ONLY|INTERNAL_CALL|CRON_JOB|BATCH_JOB)\\b[^()]*\\)/gu,\n '',\n )\n .replace(/\\s+in\\s+(?:the\\s+)?factory\\b/giu, '')\n .replace(/\\(\\s*\\)/gu, '')\n .replace(/\\s+([.,;:])/gu, '$1')\n .replace(/\\s{2,}/gu, ' ')\n .trim();\n\n/**\n * Resolve the EFFECTIVE prose for an operation, applying variant overlay\n * semantics: a present variant field REPLACES the base field; an absent\n * variant field falls back to the base. `variantKey === undefined` resolves\n * the reserved `'default'` variant.\n *\n * Returns `{}` when the spec is absent or carries no prose at all — callers\n * leave `OperationProjection.summary` / `.description` unset so the\n * generator's humanized fallback applies (graceful degradation for\n * operations / resources with no authored spec).\n */\nexport const buildOperationDocFromSpec = (\n operationSpec: OperationSpecProse | undefined,\n variantKey: string | undefined,\n): OperationDoc => {\n if (operationSpec === undefined) {\n return {};\n }\n\n const variant = operationSpec.variants?.[variantKey ?? 'default'];\n const effectivePurpose = variant?.purpose ?? operationSpec.purpose;\n const effectiveOutcome = variant?.outcome ?? operationSpec.outcome;\n const effectiveWhenToUse = variant?.whenToUse ?? operationSpec.whenToUse;\n\n const doc: OperationDoc = {};\n\n // The OpenAPI `summary` (operation TITLE / nav label / breadcrumb) is\n // intentionally NOT taken from `purpose`. `purpose` is impl-aware intent prose\n // authored for the framework-knowledge layer — a full sentence, often with\n // runtime detail like \"(API_CALL in factory)\" — which is far too long and too\n // internal to be a title. The generator derives a short verb-first title\n // (`buildDefaultSummary`); here we only build the DESCRIPTION from the authored\n // prose. The description LEADS with `purpose` (the intent), then the observable\n // `outcome`, then a \"When to use\" clause — each cleaned of implementation noise.\n const descriptionParts: string[] = [];\n if (effectivePurpose !== undefined) {\n const purpose = stripImplementationNoise(toSingleLine(effectivePurpose));\n if (purpose.length > 0) descriptionParts.push(purpose);\n }\n if (effectiveOutcome !== undefined) {\n const outcome = stripImplementationNoise(effectiveOutcome.trim());\n if (outcome.length > 0) descriptionParts.push(outcome);\n }\n if (effectiveWhenToUse !== undefined) {\n const whenToUse = stripImplementationNoise(effectiveWhenToUse.trim());\n if (whenToUse.length > 0) descriptionParts.push(`**When to use:** ${whenToUse}`);\n }\n if (descriptionParts.length > 0) {\n doc.description = clampLength(descriptionParts.join('\\n\\n'), DESCRIPTION_MAX_LENGTH);\n }\n\n return doc;\n};\n\n// ---------------------------------------------------------------------------\n// Tier 2 — field / enum documentation\n// ---------------------------------------------------------------------------\n\n/**\n * Narrow structural view of one field's authored documentation. Built by the\n * companion projector from the extracted resource field specs and consumed by\n * `injectFieldDocsIntoJsonSchema`. Boundary-clean (no `@wildo-ai/saas-specifications`\n * import): the projector maps `ExtractedFieldSpec.params.{meaning,whyItMatters,\n * relationshipContext,values}` into this shape before calling the injector.\n */\nexport interface FieldDoc {\n /** Business meaning of the field (becomes the lead of the property description). */\n meaning?: string;\n /** Why the field is included (appended to the description). */\n whyItMatters?: string;\n /** For foreign keys: the relationship this field expresses. */\n relationshipContext?: string;\n /** For enum fields: enum value string → authored meaning. */\n enumValueMeanings?: Record<string, string>;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Clean an enum value→meaning record for consumer-facing output: strip\n * implementation-only noise from each meaning (see `stripImplementationNoise`)\n * and drop any entry that is non-string or empty after cleaning. Used for both\n * the human-readable \"Values:\" legend and the machine `x-enum-descriptions`\n * extension so the two never diverge.\n */\nconst cleanEnumMeanings = (enumValueMeanings: Record<string, string>): Record<string, string> => {\n const cleaned: Record<string, string> = {};\n for (const [value, meaning] of Object.entries(enumValueMeanings)) {\n if (typeof meaning !== 'string') {\n continue;\n }\n const cleanedMeaning = stripImplementationNoise(meaning.trim());\n if (cleanedMeaning.length > 0) {\n cleaned[value] = cleanedMeaning;\n }\n }\n return cleaned;\n};\n\n/**\n * Compose a single property `description` from a field's authored docs:\n * meaning + whyItMatters + relationshipContext as space-joined sentences,\n * then an optional markdown \"Values:\" legend from enum meanings. Each authored\n * sentence is run through `stripImplementationNoise` — the field-spec prose is\n * authored for the framework-knowledge audience and may carry runtime markers\n * (`(API_CALL in factory)`) that mean nothing to an API consumer. Returns\n * `undefined` when the field carries no usable prose.\n */\nconst composeFieldDescription = (doc: FieldDoc): string | undefined => {\n const sentences: string[] = [];\n for (const candidate of [doc.meaning, doc.whyItMatters, doc.relationshipContext]) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n const cleaned = stripImplementationNoise(candidate.trim());\n if (cleaned.length > 0) {\n sentences.push(cleaned);\n }\n }\n }\n let description = sentences.join(' ');\n\n if (doc.enumValueMeanings !== undefined) {\n const legend = Object.entries(cleanEnumMeanings(doc.enumValueMeanings)).map(\n ([value, meaning]) => `- \\`${value}\\`: ${meaning}`,\n );\n if (legend.length > 0) {\n const block = `Values:\\n${legend.join('\\n')}`;\n description = description.length > 0 ? `${description}\\n\\n${block}` : block;\n }\n }\n\n return description.length > 0 ? description : undefined;\n};\n\n/**\n * Enrich the TOP-LEVEL properties of an OpenAPI/JSON-Schema object fragment\n * (a `requestBodySchema` / `responseBodySchema` produced by\n * `convertZodSchemaToOpenApiSchema`) with authored field documentation.\n * Mutates `fragment` in place.\n *\n * Rules:\n * - Property `description` is composed from the field's docs ONLY when the\n * property has no existing `description` — a Zod `.describe()` authored on\n * the DTO field wins (it is closer to the wire contract).\n * - `x-enum-descriptions` (value → meaning) is set whenever enum meanings\n * exist, independent of the description-clobber rule, for machine consumers.\n *\n * Only top-level properties are walked: the field-spec extractor produces\n * specs for top-level schema fields only, so nested-object properties have no\n * authored docs to apply. No-op for non-object fragments (`null`, scalars).\n * Joins by EXACT property-name match — DTO property names that diverge from\n * the resource's field names (renamed / computed / backend-stripped fields)\n * are simply left undocumented rather than mis-documented.\n *\n * \"Top level\" includes each branch of a top-level `oneOf` / `anyOf` / `allOf`.\n * A polymorphic resource's representation is a union whose branches carry the\n * properties themselves — the fragment has no `properties` of its own — and\n * every branch's properties are still the resource's own top-level fields. Only\n * composition keywords are entered, never an object property, so the rule above\n * still holds. Without this, 42 of the 58 properties of Wonder Todos' `todos`\n * read and list representations (`title`, `status`, `priority`, …) carried no\n * description.\n *\n * A paginated collection re-wraps those fields one level down; see\n * `injectFieldDocsIntoCollectionContract` for the two containers it adds.\n */\nexport const injectFieldDocsIntoJsonSchema = (\n fragment: unknown,\n fieldDocsByName: Record<string, FieldDoc>,\n): void => {\n if (!isPlainObject(fragment)) {\n return;\n }\n // A body that is a LIST of rows (a bulk create or update answers one row per item, #1872) documents its rows.\n if (fragment['type'] === 'array' && isPlainObject(fragment['items'])) {\n injectFieldDocsIntoJsonSchema(fragment['items'], fieldDocsByName);\n return;\n }\n for (const compositionKeyword of ['oneOf', 'anyOf', 'allOf'] as const) {\n const branches = fragment[compositionKeyword];\n if (Array.isArray(branches)) {\n for (const branch of branches) {\n injectFieldDocsIntoJsonSchema(branch, fieldDocsByName);\n }\n }\n }\n const properties = fragment['properties'];\n if (!isPlainObject(properties)) {\n return;\n }\n for (const [propertyName, rawPropertySchema] of Object.entries(properties)) {\n if (!isPlainObject(rawPropertySchema)) {\n continue;\n }\n const doc = fieldDocsByName[propertyName];\n if (doc === undefined) {\n continue;\n }\n if (rawPropertySchema['description'] === undefined) {\n const description = composeFieldDescription(doc);\n if (description !== undefined) {\n rawPropertySchema['description'] = description;\n }\n }\n if (doc.enumValueMeanings !== undefined) {\n const cleanedEnumMeanings = cleanEnumMeanings(doc.enumValueMeanings);\n if (Object.keys(cleanedEnumMeanings).length > 0) {\n rawPropertySchema['x-enum-descriptions'] = cleanedEnumMeanings;\n }\n }\n }\n};\n\n/**\n * Enrich the two places a paginated collection contract carries the resource's OWN fields one\n * level down, where `injectFieldDocsIntoJsonSchema` (top level only) cannot reach them:\n *\n * - the request's `filters` object — one property per filterable field, which the generator\n * flattens into query parameters (`?status=…`), copying each property's `description`;\n * - the response envelope's `data[]` items — the resource rows a LIST / SEARCH returns.\n *\n * This is not the general nested walk `injectFieldDocsIntoJsonSchema` declines: a nested object's\n * properties have no field specification, while these two containers hold the resource's own\n * top-level fields, re-wrapped by the framework's collection contract. Before this, 59% of the\n * list-item properties and 219 query filters in the Wonder Todos document carried no description,\n * although the same fields were fully described in the read and create responses.\n *\n * Call it only for a paginated collection operation (LIST, or SEARCH-like). Anything else passes\n * through unchanged, because neither container exists.\n */\nexport const injectFieldDocsIntoCollectionContract = (\n requestBodySchema: unknown,\n responseBodySchema: unknown,\n fieldDocsByName: Record<string, FieldDoc>,\n): void => {\n const filters = isPlainObject(requestBodySchema) && isPlainObject(requestBodySchema['properties'])\n ? requestBodySchema['properties']['filters']\n : undefined;\n injectFieldDocsIntoJsonSchema(filters, fieldDocsByName);\n const data = isPlainObject(responseBodySchema) && isPlainObject(responseBodySchema['properties'])\n ? responseBodySchema['properties']['data']\n : undefined;\n const items = isPlainObject(data) ? data['items'] : undefined;\n injectFieldDocsIntoJsonSchema(items, fieldDocsByName);\n injectNestedFilterDescriptionsFromRows(filters, items);\n};\n\n/**\n * A filter on a nested field is keyed by its dotted path (`linkedResource.resourceType`, #1630), so it\n * matches no field specification by name and was published with no description. The field it filters\n * is described where it is declared — in the row schema the same collection returns — so the filter\n * takes that description, found by walking the row along the path. Only a filter that has none of its\n * own is filled in, and a path the rows do not carry (or reach only through a `$ref`) is left as is.\n */\nconst injectNestedFilterDescriptionsFromRows = (filters: unknown, rowSchema: unknown): void => {\n if (!isPlainObject(filters) || !isPlainObject(filters['properties'])) {\n return;\n }\n for (const [filterName, filterSchema] of Object.entries(filters['properties'])) {\n if (!filterName.includes('.') || !isPlainObject(filterSchema) || filterSchema['description'] !== undefined) {\n continue;\n }\n const description = describedPropertyAtPath(rowSchema, filterName.split('.'));\n if (description !== undefined) {\n filterSchema['description'] = description;\n }\n }\n};\n\n/**\n * The description of the property `path` names inside `schema`, entering `oneOf` / `anyOf` / `allOf`\n * branches at each step — a nullable object is `anyOf [object, null]` — and taking the first branch\n * that has the property.\n */\nconst describedPropertyAtPath = (schema: unknown, path: readonly string[]): string | undefined => {\n if (!isPlainObject(schema) || path.length === 0) {\n return undefined;\n }\n const [head, ...rest] = path;\n const properties = schema['properties'];\n if (isPlainObject(properties) && isPlainObject(properties[head!])) {\n const property = properties[head!] as Record<string, unknown>;\n if (rest.length === 0) {\n return typeof property['description'] === 'string' ? property['description'] : undefined;\n }\n const found = describedPropertyAtPath(property, rest);\n if (found !== undefined) {\n return found;\n }\n }\n for (const compositionKeyword of ['oneOf', 'anyOf', 'allOf'] as const) {\n const branches = schema[compositionKeyword];\n if (!Array.isArray(branches)) {\n continue;\n }\n for (const branch of branches) {\n const found = describedPropertyAtPath(branch, path);\n if (found !== undefined) {\n return found;\n }\n }\n }\n return undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Tier 3 — operation HTTP documentation (response statuses / errors / examples)\n// ---------------------------------------------------------------------------\n\n/**\n * Projection-shaped HTTP documentation for one operation (Tier 3). Mirrors the\n * authored `ResourceOperationSpecification` HTTP fields, normalized to plain\n * JSON the OpenAPI generator emits as `responses` / `examples` / extensions.\n */\n/**\n * One documented failure mode, with the error-body field each identifier appears in.\n *\n * `errorType` is `error.type`, `customMessageReference` is `error.customMessageReference`, and\n * `errorCode` is `error.code` — three different fields a client branches on, carried separately\n * because the authored specification names them separately (see\n * `ResourceOperationErrorScenarioSpecification`). Values are the wire strings.\n */\nexport interface OperationErrorScenarioDoc {\n code: string;\n when: string;\n errorType?: string;\n customMessageReference?: string;\n errorCode?: string;\n}\n\nexport interface OperationHttpDoc {\n responseStatuses?: Array<{ code: string; meaning: string }>;\n errorScenarios?: OperationErrorScenarioDoc[];\n idempotent?: boolean;\n rateLimitNote?: string;\n examples?: Array<{ title: string; request?: unknown; response?: unknown; forStatus?: string }>;\n}\n\nconst asNonEmptyString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n\n/**\n * Like `asNonEmptyString`, but for PROSE fields surfaced verbatim to API\n * consumers (response-status `meaning`, error-scenario `when`, example `title`,\n * `rateLimitNote`): additionally strips implementation-only noise (see\n * `stripImplementationNoise`) and returns `undefined` if the value is empty\n * before OR after cleaning. Do NOT use for code-like fields (`code`, `errorType`,\n * `customMessageReference`, `errorCode`, `forStatus`) — those pass through untouched via\n * `asNonEmptyString`.\n */\nconst asCleanProse = (value: unknown): string | undefined => {\n const raw = asNonEmptyString(value);\n if (raw === undefined) {\n return undefined;\n }\n const cleaned = stripImplementationNoise(raw);\n return cleaned.length > 0 ? cleaned : undefined;\n};\n\n/**\n * Extract + normalize the Tier-3 HTTP-documentation fields from a raw authored\n * operation spec into the projection shape. Variant examples are a complete\n * overlay: when `variants.<key>.examples` is present it replaces the base\n * operation examples, rather than merging a payload that may target a different\n * response schema. Defensive: a malformed entry is dropped rather than\n * poisoning the whole projection (the generator re-validates via Zod). Returns\n * `{}` when the operation authored no HTTP docs.\n *\n * Prose fields (`meaning` / `when` / `title` / `rateLimitNote`) are cleaned of\n * implementation-only noise via `asCleanProse`, consistent with the Tier-1\n * `description` and Tier-2 field descriptions. `code` / `forStatus` are\n * `HttpResponseStatusCode` values whose runtime string (`'200'`, …) is the OpenAPI\n * `responses` key; `errorType` / `customMessageReference` / `errorCode` are the\n * error-body wire values a client branches on. All pass through untouched.\n */\nexport const buildOperationHttpDocFromSpec = (operationSpec: unknown, variantKey?: string): OperationHttpDoc => {\n if (!isPlainObject(operationSpec)) {\n return {};\n }\n const doc: OperationHttpDoc = {};\n\n const responseStatuses = operationSpec['responseStatuses'];\n if (Array.isArray(responseStatuses)) {\n const normalized = responseStatuses\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const code = asNonEmptyString(entry['code']);\n const meaning = asCleanProse(entry['meaning']);\n return code !== undefined && meaning !== undefined ? { code, meaning } : undefined;\n })\n .filter((entry): entry is { code: string; meaning: string } => entry !== undefined);\n if (normalized.length > 0) doc.responseStatuses = normalized;\n }\n\n const errorScenarios = operationSpec['errorScenarios'];\n if (Array.isArray(errorScenarios)) {\n const normalized = errorScenarios\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const code = asNonEmptyString(entry['code']);\n const when = asCleanProse(entry['when']);\n if (code === undefined || when === undefined) return undefined;\n const scenario: OperationErrorScenarioDoc = { code, when };\n const errorType = asNonEmptyString(entry['errorType']);\n if (errorType !== undefined) scenario.errorType = errorType;\n const customMessageReference = asNonEmptyString(entry['customMessageReference']);\n if (customMessageReference !== undefined) scenario.customMessageReference = customMessageReference;\n const errorCode = asNonEmptyString(entry['errorCode']);\n if (errorCode !== undefined) scenario.errorCode = errorCode;\n return scenario;\n })\n .filter((entry): entry is OperationErrorScenarioDoc => entry !== undefined);\n if (normalized.length > 0) doc.errorScenarios = normalized;\n }\n\n if (typeof operationSpec['idempotent'] === 'boolean') {\n doc.idempotent = operationSpec['idempotent'];\n }\n\n const rateLimitNote = asCleanProse(operationSpec['rateLimitNote']);\n if (rateLimitNote !== undefined) {\n doc.rateLimitNote = rateLimitNote;\n }\n\n const variants = operationSpec['variants'];\n const variant = isPlainObject(variants) ? variants[variantKey ?? 'default'] : undefined;\n // A present variant `examples` member deliberately suppresses the base even\n // when it is malformed or empty: falling back would publish a payload under a\n // schema the variant does not own. The normalizer below emits no example for\n // that invalid/empty override, which is safer than a misleading one.\n const examples =\n isPlainObject(variant) && Object.prototype.hasOwnProperty.call(variant, 'examples')\n ? variant['examples']\n : operationSpec['examples'];\n if (Array.isArray(examples)) {\n const normalized = examples\n .map((entry) => {\n if (!isPlainObject(entry)) return undefined;\n const title = asCleanProse(entry['title']);\n if (title === undefined) return undefined;\n const example: { title: string; request?: unknown; response?: unknown; forStatus?: string } = { title };\n if (entry['request'] !== undefined) example.request = entry['request'];\n if (entry['response'] !== undefined) example.response = entry['response'];\n const forStatus = asNonEmptyString(entry['forStatus']);\n if (forStatus !== undefined) example.forStatus = forStatus;\n return example;\n })\n .filter(\n (entry): entry is { title: string; request?: unknown; response?: unknown; forStatus?: string } =>\n entry !== undefined,\n );\n if (normalized.length > 0) doc.examples = normalized;\n }\n\n return doc;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-asset-path.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-asset-path.d.ts","sourceRoot":"","sources":["../../../src/companion/technical-documentation-asset-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,+BAA+B,EAChC,MAAM,uDAAuD,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,gGAAgG;AAChG,wBAAgB,gDAAgD,CAAC,KAAK,EAAE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,CAIT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-capture-execution-port.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-capture-execution-port.d.ts","sourceRoot":"","sources":["../../../src/companion/technical-documentation-capture-execution-port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,+CAA+C,EAC/C,sCAAsC,EACvC,MAAM,uDAAuD,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,CAAC,OAAO,EAAE,sCAAsC,CAAC;IACzD,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,0CAA0C;IACzD,OAAO,CAAC,OAAO,EAAE,+CAA+C,GAAG,OAAO,CAAC,4CAA4C,CAAC,CAAC;CAC1H"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"technical-documentation-diagram-definitions.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"technical-documentation-diagram-definitions.d.ts","sourceRoot":"","sources":["../../../src/companion/technical-documentation-diagram-definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAML,KAAK,oCAAoC,EAC1C,MAAM,uDAAuD,CAAC;AAE/D,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uCAAuC;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,iCAAiC,EAAE,CAAC;IAC7D,QAAQ,CAAC,KAAK,EAAE,SAAS,iCAAiC,EAAE,CAAC;CAC9D;AAED,eAAO,MAAM,sDAAsD,EAAE,uCAYnE,CAAC;AAEH,wBAAgB,iEAAiE,IAAI,oCAAoC,CAwBxH"}
|