@ankhorage/paradox 0.1.27 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +53 -61
  3. package/dist/analyze/analyze.d.ts +2 -2
  4. package/dist/analyze/analyze.js +51 -35
  5. package/dist/analyze/badges.d.ts +2 -1
  6. package/dist/analyze/badges.js +14 -4
  7. package/dist/analyze/components.js +12 -11
  8. package/dist/analyze/documentation/collectDocumentationCommentsAsync.d.ts +11 -0
  9. package/dist/analyze/documentation/collectDocumentationCommentsAsync.js +72 -0
  10. package/dist/analyze/documentation/findings.d.ts +5 -0
  11. package/dist/analyze/documentation/findings.js +17 -0
  12. package/dist/analyze/documentation/validateDocumentationPolicyAsync.d.ts +13 -0
  13. package/dist/analyze/documentation/validateDocumentationPolicyAsync.js +150 -0
  14. package/dist/analyze/documentation/validateReferencesAsync.d.ts +11 -0
  15. package/dist/analyze/documentation/validateReferencesAsync.js +148 -0
  16. package/dist/analyze/exports.d.ts +4 -0
  17. package/dist/analyze/exports.js +14 -7
  18. package/dist/analyze/readmeConfig.d.ts +1 -3
  19. package/dist/analyze/readmeConfig.js +8 -19
  20. package/dist/analyze/readmeUsage.d.ts +7 -10
  21. package/dist/analyze/readmeUsage.js +124 -48
  22. package/dist/analyze/semantic/docBlocks.js +18 -48
  23. package/dist/analyze/semantic/exports.js +1 -3
  24. package/dist/analyze/semantic/model.d.ts +0 -2
  25. package/dist/analyze/semantic/paradoxComment.d.ts +1 -11
  26. package/dist/analyze/semantic/paradoxComment.js +1 -43
  27. package/dist/analyze/semantic/tagRegistry.js +2 -1
  28. package/dist/analyze/sourceFunctions.js +4 -4
  29. package/dist/analyze/types.d.ts +31 -24
  30. package/dist/analyze/usage.d.ts +2 -2
  31. package/dist/analyze/usage.js +3 -33
  32. package/dist/analyze/utils/getExportMetadata.js +11 -40
  33. package/dist/analyze/utils/parseParadoxComment.d.ts +12 -9
  34. package/dist/analyze/utils/parseParadoxComment.js +66 -78
  35. package/dist/cli/index.d.ts +3 -2
  36. package/dist/cli/index.js +3 -2
  37. package/dist/cli/standalone.js +11 -0
  38. package/dist/config/defineParadoxConfig.d.ts +1 -1
  39. package/dist/doc-tags/registry.d.ts +28 -32
  40. package/dist/doc-tags/registry.js +35 -39
  41. package/dist/index.d.ts +1 -1
  42. package/dist/model/buildModel.d.ts +26 -19
  43. package/dist/model/buildModel.js +33 -99
  44. package/dist/model/types.d.ts +27 -20
  45. package/dist/paths/policy.d.ts +1 -1
  46. package/dist/render/renderers/diagrams.js +1 -7
  47. package/dist/render/renderers/html.js +89 -58
  48. package/dist/render/renderers/markdown.js +139 -86
  49. package/dist/render/toFileStem.d.ts +2 -0
  50. package/dist/render/toFileStem.js +8 -0
  51. package/dist/{config/types.d.ts → types/config.d.ts} +3 -5
  52. package/dist/write/write.d.ts +1 -1
  53. package/package.json +2 -1
  54. package/dist/analyze/readmeCli.d.ts +0 -9
  55. package/dist/analyze/readmeCli.js +0 -33
  56. package/dist/analyze/utils/getLeadingParadoxComment.d.ts +0 -10
  57. package/dist/analyze/utils/getLeadingParadoxComment.js +0 -16
  58. /package/dist/{config/types.js → types/config.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  /***
2
- * Generates deterministic documentation for a package through the Paradox CLI.
2
+ * Exposes the Paradox command provider through the canonical Ankhorage CLI surface.
3
3
  *
4
- * @readme
4
+ * @title CLI
5
+ * @usage
5
6
  */
6
7
  export { default } from '../docsSurface.js';
package/dist/cli/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /***
2
- * Generates deterministic documentation for a package through the Paradox CLI.
2
+ * Exposes the Paradox command provider through the canonical Ankhorage CLI surface.
3
3
  *
4
- * @readme
4
+ * @title CLI
5
+ * @usage
5
6
  */
6
7
  export { default } from '../docsSurface.js';
@@ -23,10 +23,21 @@ async function main() {
23
23
  const packageRoot = await resolvePackageRoot(config, configDir);
24
24
  const { outputDir, outputRoot } = resolveOutputRoot(config, packageRoot);
25
25
  const analysis = await analyze(config, { packageRoot, configFilePath });
26
+ assertNoDocumentationErrors(analysis.findings);
26
27
  const model = buildModel(analysis);
27
28
  const result = render(model, { outputDir });
28
29
  await write(result, config, { packageRoot, outputRoot });
29
30
  }
31
+ /***
32
+ * Refuses to write generated artifacts when canonical documentation policy contains errors.
33
+ */
34
+ function assertNoDocumentationErrors(findings) {
35
+ const errors = findings.filter((finding) => finding.severity === 'error');
36
+ if (errors.length === 0)
37
+ return;
38
+ const details = errors.map((finding) => `- [${finding.ruleId}] ${finding.message}`).join('\n');
39
+ throw new Error(`Paradox documentation policy is invalid:\n${details}`);
40
+ }
30
41
  main().catch((error) => {
31
42
  console.error(error);
32
43
  process.exit(1);
@@ -1,4 +1,4 @@
1
- import type { ParadoxConfig } from './types.js';
1
+ import type { ParadoxConfig } from '../types/config.js';
2
2
  /***
3
3
  * Defines a Paradox configuration object without changing its shape.
4
4
  *
@@ -1,39 +1,35 @@
1
- export declare const PARADOX_DOC_TAGS: readonly [{
2
- readonly name: "readme";
3
- readonly syntax: "@readme";
4
- readonly description: "Includes a documentation block or exported symbol in README output.";
5
- readonly appliesTo: readonly ["block", "symbol"];
6
- readonly repeatable: false;
7
- readonly handler: "markReadme";
8
- }, {
9
- readonly name: "config";
10
- readonly syntax: "@config";
11
- readonly description: "Marks a configuration type, interface, or source block. Pair with @readme to include the schema or actual config source in README Configuration output.";
12
- readonly appliesTo: readonly ["block", "interface", "type"];
13
- readonly repeatable: false;
14
- readonly handler: "markConfig";
15
- }, {
16
- readonly name: "example";
17
- readonly syntax: "@example";
18
- readonly description: "Adds a titled fenced code example to the generated documentation for a symbol.";
19
- readonly appliesTo: readonly ["symbol"];
20
- readonly repeatable: true;
21
- readonly handler: "parseExample";
22
- }, {
23
- readonly name: "usage";
24
- readonly syntax: "@usage";
25
- readonly description: "Promotes a real source example into the generated README Usage section.";
26
- readonly appliesTo: readonly ["block", "symbol"];
27
- readonly repeatable: false;
28
- readonly handler: "markUsage";
29
- }];
30
- export type ParadoxDocTagName = (typeof PARADOX_DOC_TAGS)[number]['name'];
31
- export type ParadoxDocTagHandlerId = (typeof PARADOX_DOC_TAGS)[number]['handler'];
1
+ import { type DocumentationTagName, type DocumentationTagTarget, type DocumentationTagValueKind } from '@ankhorage/policy/documentation';
2
+ declare const HANDLERS: {
3
+ readonly readme: "markReadme";
4
+ readonly usage: "markUsage";
5
+ readonly config: "markConfig";
6
+ readonly title: "setTitle";
7
+ readonly see: "addSee";
8
+ readonly security: "addSecurity";
9
+ };
10
+ interface ParadoxDocTag {
11
+ name: DocumentationTagName;
12
+ syntax: string;
13
+ description: string;
14
+ appliesTo: readonly DocumentationTagTarget[];
15
+ repeatable: boolean;
16
+ valueKind: DocumentationTagValueKind;
17
+ handler: (typeof HANDLERS)[DocumentationTagName];
18
+ }
19
+ /***
20
+ * Supported Paradox documentation tags projected from the canonical Ankhorage documentation policy.
21
+ *
22
+ * @readme
23
+ */
24
+ export declare const PARADOX_DOC_TAGS: readonly ParadoxDocTag[];
25
+ export type ParadoxDocTagName = DocumentationTagName;
26
+ export type ParadoxDocTagHandlerId = (typeof HANDLERS)[DocumentationTagName];
32
27
  /***
33
28
  * Looks up documentation tag metadata by tag name.
34
29
  */
35
- export declare function getParadoxDocTag(name: string): (typeof PARADOX_DOC_TAGS)[number] | null;
30
+ export declare function getParadoxDocTag(name: string): ParadoxDocTag | null;
36
31
  /***
37
32
  * Checks whether a string is a supported Paradox documentation tag name.
38
33
  */
39
34
  export declare function isParadoxDocTagName(name: string): name is ParadoxDocTagName;
35
+ export {};
@@ -1,46 +1,23 @@
1
+ import { DOCUMENTATION_POLICY, } from '@ankhorage/policy/documentation';
2
+ const HANDLERS = {
3
+ readme: 'markReadme',
4
+ usage: 'markUsage',
5
+ config: 'markConfig',
6
+ title: 'setTitle',
7
+ see: 'addSee',
8
+ security: 'addSecurity',
9
+ };
1
10
  /***
2
- * Supported Paradox documentation tags.
3
- *
4
- * Paradox supports doc tags inside triple-star documentation comments.
11
+ * Supported Paradox documentation tags projected from the canonical Ankhorage documentation policy.
5
12
  *
6
13
  * @readme
7
14
  */
8
- const DOC_TAG_PREFIX = '\u0040';
9
- const USAGE_DOC_TAG = `${DOC_TAG_PREFIX}usage`;
10
- export const PARADOX_DOC_TAGS = [
11
- {
12
- name: 'readme',
13
- syntax: '@readme',
14
- description: 'Includes a documentation block or exported symbol in README output.',
15
- appliesTo: ['block', 'symbol'],
16
- repeatable: false,
17
- handler: 'markReadme',
18
- },
19
- {
20
- name: 'config',
21
- syntax: '@config',
22
- description: 'Marks a configuration type, interface, or source block. Pair with @readme to include the schema or actual config source in README Configuration output.',
23
- appliesTo: ['block', 'interface', 'type'],
24
- repeatable: false,
25
- handler: 'markConfig',
26
- },
27
- {
28
- name: 'example',
29
- syntax: '@example',
30
- description: 'Adds a titled fenced code example to the generated documentation for a symbol.',
31
- appliesTo: ['symbol'],
32
- repeatable: true,
33
- handler: 'parseExample',
34
- },
35
- {
36
- name: 'usage',
37
- syntax: USAGE_DOC_TAG,
38
- description: 'Promotes a real source example into the generated README Usage section.',
39
- appliesTo: ['block', 'symbol'],
40
- repeatable: false,
41
- handler: 'markUsage',
42
- },
43
- ];
15
+ export const PARADOX_DOC_TAGS = DOCUMENTATION_POLICY.tags.map((tag) => ({
16
+ ...tag,
17
+ syntax: `@${tag.name}`,
18
+ description: describeTag(tag.name),
19
+ handler: HANDLERS[tag.name],
20
+ }));
44
21
  /***
45
22
  * Looks up documentation tag metadata by tag name.
46
23
  */
@@ -53,3 +30,22 @@ export function getParadoxDocTag(name) {
53
30
  export function isParadoxDocTagName(name) {
54
31
  return getParadoxDocTag(name) !== null;
55
32
  }
33
+ /***
34
+ * Describes the rendering meaning of one policy-owned documentation tag.
35
+ */
36
+ function describeTag(name) {
37
+ switch (name) {
38
+ case 'readme':
39
+ return 'Promotes the documented item into generated README output.';
40
+ case 'usage':
41
+ return 'Marks real source as package usage documentation.';
42
+ case 'config':
43
+ return 'Marks the canonical package configuration schema root.';
44
+ case 'title':
45
+ return 'Provides an explicit presentation title for a documented item.';
46
+ case 'see':
47
+ return 'Adds a validated external documentation reference.';
48
+ case 'security':
49
+ return 'Links security-sensitive behavior to an exact colocated executable test.';
50
+ }
51
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { defineParadoxConfig } from './config/defineParadoxConfig.js';
2
- export type { ParadoxConfig } from './config/types.js';
3
2
  export type { ParadoxDocTagHandlerId, ParadoxDocTagName } from './doc-tags/registry.js';
4
3
  export { getParadoxDocTag, isParadoxDocTagName, PARADOX_DOC_TAGS } from './doc-tags/registry.js';
5
4
  export { packageMetadata as paradoxPackageMetadata } from './packageMetadata.js';
5
+ export type { ParadoxConfig } from './types/config.js';
@@ -1,9 +1,4 @@
1
1
  import type { DocumentationModel, ExportKind } from './types.js';
2
- interface ExampleInput {
3
- title: string | null;
4
- language: string | null;
5
- code: string;
6
- }
7
2
  interface ExportMemberInput {
8
3
  name: string;
9
4
  kind: 'property' | 'method';
@@ -39,9 +34,11 @@ interface BuildModelInput {
39
34
  }[];
40
35
  exports: {
41
36
  name: string;
37
+ title: string | null;
42
38
  description: string | null;
43
39
  isReadme: boolean;
44
- examples: ExampleInput[];
40
+ see: string[];
41
+ security: string[];
45
42
  kind: ExportKind;
46
43
  modulePath: string;
47
44
  sourceLocation: {
@@ -71,7 +68,8 @@ interface BuildModelInput {
71
68
  name: string;
72
69
  description: string | null;
73
70
  isReadme: boolean;
74
- examples: ExampleInput[];
71
+ see: string[];
72
+ security: string[];
75
73
  modulePath: string;
76
74
  sourceLocation: {
77
75
  filePath: string;
@@ -90,6 +88,8 @@ interface BuildModelInput {
90
88
  sourceFunctions: {
91
89
  name: string;
92
90
  description: string | null;
91
+ see: string[];
92
+ security: string[];
93
93
  sourceLocation: {
94
94
  filePath: string;
95
95
  line: number;
@@ -106,32 +106,39 @@ interface BuildModelInput {
106
106
  }[];
107
107
  usage: {
108
108
  packageName: string;
109
- commands: {
110
- name: string;
111
- command: string;
112
- }[];
113
- } | null;
114
- readmeUsageDescription: string | null;
115
- readmeUsage: {
109
+ command: string;
110
+ };
111
+ usageEntries: {
112
+ area: 'cli' | 'examples';
116
113
  title: string | null;
117
114
  description: string | null;
118
115
  language: string;
119
116
  code: string;
120
117
  sourcePath: string;
118
+ isReadme: boolean;
119
+ see: string[];
120
+ security: string[];
121
+ }[];
122
+ exampleCount: number;
123
+ findings: {
124
+ ruleId: string;
125
+ severity: 'warning' | 'error';
126
+ message: string;
127
+ sourcePath: string | null;
128
+ line: number | null;
121
129
  }[];
122
- readmeCli: {
123
- description: string | null;
124
- sourcePath: string;
125
- } | null;
126
130
  readmeConfig: {
127
- description: string | null;
128
131
  language: string;
129
132
  code: string;
130
133
  sourcePath: string;
131
134
  } | null;
132
135
  config: {
133
136
  exportName: string;
137
+ title: string | null;
138
+ description: string | null;
134
139
  isReadme: boolean;
140
+ see: string[];
141
+ security: string[];
135
142
  members: ConfigMemberInput[];
136
143
  } | null;
137
144
  entrypoints: string[];
@@ -4,87 +4,45 @@
4
4
  export function buildModel(analysis) {
5
5
  const exportNames = new Set(analysis.exports.map((item) => item.name));
6
6
  const exportsByName = new Map(analysis.exports.map((item) => [item.name, mapExport(item, exportNames)]));
7
- const exports = sortByName([...exportsByName.values()]);
8
7
  return {
9
8
  packageName: analysis.packageName,
10
9
  packageId: analysis.packageId,
11
10
  description: analysis.description,
12
11
  collaborators: analysis.collaborators,
13
12
  donation: analysis.donation === null ? null : { account: analysis.donation.account },
14
- badges: analysis.badges.map((badge) => ({
15
- id: badge.id,
16
- label: badge.label,
17
- value: badge.value,
18
- color: badge.color,
19
- })),
20
- usage: analysis.usage !== null
21
- ? {
22
- packageName: analysis.usage.packageName,
23
- commands: sortByName(analysis.usage.commands.map((command) => ({
24
- name: command.name,
25
- command: command.command,
26
- }))),
27
- }
28
- : null,
29
- readmeUsageDescription: analysis.readmeUsageDescription,
30
- readmeUsage: analysis.readmeUsage
31
- .map((usageEntry) => ({
32
- title: usageEntry.title,
33
- description: usageEntry.description,
34
- language: usageEntry.language,
35
- code: usageEntry.code,
36
- sourcePath: usageEntry.sourcePath,
37
- }))
13
+ badges: analysis.badges.map((badge) => ({ ...badge })),
14
+ usage: { ...analysis.usage },
15
+ usageEntries: analysis.usageEntries
16
+ .map((entry) => ({ ...entry, see: [...entry.see], security: [...entry.security] }))
38
17
  .sort((left, right) => left.sourcePath.localeCompare(right.sourcePath)),
39
- readmeCli: analysis.readmeCli !== null
40
- ? {
41
- description: analysis.readmeCli.description,
42
- sourcePath: analysis.readmeCli.sourcePath,
43
- }
44
- : null,
45
- readmeConfig: analysis.readmeConfig !== null
46
- ? {
47
- description: analysis.readmeConfig.description,
48
- language: analysis.readmeConfig.language,
49
- code: analysis.readmeConfig.code,
50
- sourcePath: analysis.readmeConfig.sourcePath,
51
- }
52
- : null,
53
- config: analysis.config !== null
54
- ? {
55
- exportName: analysis.config.exportName,
56
- isReadme: analysis.config.isReadme,
18
+ exampleCount: analysis.exampleCount,
19
+ findings: analysis.findings.map((finding) => ({ ...finding })),
20
+ readmeConfig: analysis.readmeConfig === null ? null : { ...analysis.readmeConfig },
21
+ config: analysis.config === null
22
+ ? null
23
+ : {
24
+ ...analysis.config,
25
+ see: [...analysis.config.see],
26
+ security: [...analysis.config.security],
57
27
  members: analysis.config.members,
58
- }
59
- : null,
28
+ },
60
29
  entrypoints: [...analysis.entrypoints].sort((a, b) => a.localeCompare(b)),
61
30
  modules: [...analysis.modules]
62
31
  .map((module) => ({
63
- path: module.path,
64
- isEntrypoint: module.isEntrypoint,
32
+ ...module,
65
33
  dependencies: [...module.dependencies].sort((a, b) => a.localeCompare(b)),
66
34
  exports: [...module.exports].sort((a, b) => a.localeCompare(b)),
67
35
  }))
68
36
  .sort((left, right) => left.path.localeCompare(right.path)),
69
- exports,
37
+ exports: sortByName([...exportsByName.values()]),
70
38
  components: sortByName(analysis.components.map((component) => mapComponent(component, exportsByName.get(component.name)))),
71
39
  sourceFunctions: analysis.sourceFunctions.map((sourceFunction) => ({
72
- name: sourceFunction.name,
73
- description: sourceFunction.description,
74
- sourceLocation: {
75
- filePath: sourceFunction.sourceLocation.filePath,
76
- line: sourceFunction.sourceLocation.line,
77
- column: sourceFunction.sourceLocation.column,
78
- },
40
+ ...sourceFunction,
41
+ see: [...sourceFunction.see],
42
+ security: [...sourceFunction.security],
43
+ sourceLocation: { ...sourceFunction.sourceLocation },
79
44
  })),
80
- sequenceScenarios: sortByName(analysis.sequenceScenarios.map((scenario) => ({
81
- kind: scenario.kind,
82
- name: scenario.name,
83
- sourcePath: scenario.sourcePath,
84
- symbolName: scenario.symbolName,
85
- description: scenario.description,
86
- isReadme: scenario.isReadme,
87
- }))),
45
+ sequenceScenarios: sortByName(analysis.sequenceScenarios.map((scenario) => ({ ...scenario }))),
88
46
  graphs: {
89
47
  imports: [...analysis.graphs.imports],
90
48
  calls: [...analysis.graphs.calls],
@@ -99,39 +57,24 @@ export function buildModel(analysis) {
99
57
  function mapExport(item, exportNames) {
100
58
  return {
101
59
  name: item.name,
60
+ title: item.title,
102
61
  description: item.description,
103
62
  isReadme: item.isReadme,
104
- examples: item.examples.map((example) => ({ ...example })),
63
+ see: [...item.see],
64
+ security: [...item.security],
105
65
  kind: item.kind,
106
66
  modulePath: item.modulePath,
107
- sourceLocation: {
108
- filePath: item.sourceLocation.filePath,
109
- line: item.sourceLocation.line,
110
- column: item.sourceLocation.column,
111
- },
67
+ sourceLocation: { ...item.sourceLocation },
112
68
  exportPaths: [...item.exportPaths].sort((a, b) => a.localeCompare(b)),
113
69
  relatedSymbols: item.relatedSymbols
114
70
  .filter((symbol) => exportNames.has(symbol))
115
71
  .sort((a, b) => a.localeCompare(b)),
116
72
  signatures: item.signatures.map((signature) => ({
117
- label: signature.label,
118
- parameters: sortByName(signature.parameters.map((parameter) => ({
119
- name: parameter.name,
120
- type: parameter.type,
121
- required: parameter.required,
122
- description: parameter.description,
123
- }))),
124
- returnType: signature.returnType,
125
- returnDescription: signature.returnDescription,
73
+ ...signature,
74
+ parameters: sortByName(signature.parameters.map((parameter) => ({ ...parameter }))),
126
75
  })),
127
76
  members: sortByName(item.members.map((member) => ({
128
- name: member.name,
129
- kind: member.kind,
130
- type: member.type,
131
- required: member.required,
132
- description: member.description,
133
- defaultValue: member.defaultValue,
134
- inheritedFrom: member.inheritedFrom,
77
+ ...member,
135
78
  children: member.children,
136
79
  }))),
137
80
  structuredRows: item.structuredRows.map((row) => ({ values: { ...row.values } })),
@@ -145,25 +88,16 @@ function mapComponent(component, exportModel) {
145
88
  name: component.name,
146
89
  description: component.description,
147
90
  isReadme: component.isReadme,
148
- examples: component.examples.map((example) => ({ ...example })),
91
+ see: [...component.see],
92
+ security: [...component.security],
149
93
  modulePath: component.modulePath,
150
- sourceLocation: {
151
- filePath: component.sourceLocation.filePath,
152
- line: component.sourceLocation.line,
153
- column: component.sourceLocation.column,
154
- },
94
+ sourceLocation: { ...component.sourceLocation },
155
95
  exportPaths: exportModel?.exportPaths ?? [...component.exportPaths].sort((a, b) => a.localeCompare(b)),
156
- props: sortByName(component.props.map((prop) => ({
157
- name: prop.name,
158
- type: prop.type,
159
- required: prop.required,
160
- defaultValue: prop.defaultValue,
161
- description: prop.description,
162
- }))),
96
+ props: sortByName(component.props.map((prop) => ({ ...prop }))),
163
97
  };
164
98
  }
165
99
  /***
166
- * Returns a copy of items sorted by their `name` property.
100
+ * Returns a copy of items sorted by their name property.
167
101
  */
168
102
  function sortByName(items) {
169
103
  return [...items].sort((a, b) => a.name.localeCompare(b.name));
@@ -1,3 +1,4 @@
1
+ import type { PolicySeverity } from '@ankhorage/policy/status';
1
2
  /***
2
3
  * Serializable model consumed by renderers and writers.
3
4
  */
@@ -8,10 +9,10 @@ export interface DocumentationModel {
8
9
  collaborators: true | null;
9
10
  donation: DonationModel | null;
10
11
  badges: GeneratedBadge[];
11
- usage: UsageModel | null;
12
- readmeUsageDescription: string | null;
13
- readmeUsage: ReadmeUsageModel[];
14
- readmeCli: ReadmeCliModel | null;
12
+ usage: UsageModel;
13
+ usageEntries: UsageEntryModel[];
14
+ exampleCount: number;
15
+ findings: DocumentationFindingModel[];
15
16
  readmeConfig: ReadmeConfigModel | null;
16
17
  config: ConfigModel | null;
17
18
  entrypoints: string[];
@@ -33,39 +34,47 @@ export interface GeneratedBadge {
33
34
  }
34
35
  interface UsageModel {
35
36
  packageName: string;
36
- commands: UsageCommandModel[];
37
- }
38
- interface UsageCommandModel {
39
- name: string;
40
37
  command: string;
41
38
  }
42
- interface ReadmeUsageModel {
39
+ interface UsageEntryModel {
40
+ area: 'cli' | 'examples';
43
41
  title: string | null;
44
42
  description: string | null;
45
43
  language: string;
46
44
  code: string;
47
45
  sourcePath: string;
46
+ isReadme: boolean;
47
+ see: string[];
48
+ security: string[];
48
49
  }
49
- interface ReadmeCliModel {
50
- description: string | null;
51
- sourcePath: string;
50
+ interface DocumentationFindingModel {
51
+ ruleId: string;
52
+ severity: PolicySeverity;
53
+ message: string;
54
+ sourcePath: string | null;
55
+ line: number | null;
52
56
  }
53
57
  interface ReadmeConfigModel {
54
- description: string | null;
55
58
  language: string;
56
59
  code: string;
57
60
  sourcePath: string;
58
61
  }
59
62
  interface ConfigModel {
60
63
  exportName: string;
64
+ title: string | null;
65
+ description: string | null;
61
66
  isReadme: boolean;
67
+ see: string[];
68
+ security: string[];
62
69
  members: ConfigMemberModel[];
63
70
  }
64
71
  export interface ExportModel {
65
72
  name: string;
73
+ title: string | null;
66
74
  description: string | null;
67
75
  isReadme: boolean;
68
- examples: ExampleModel[];
76
+ see: string[];
77
+ security: string[];
69
78
  kind: ExportKind;
70
79
  modulePath: string;
71
80
  sourceLocation: SourceLocationModel;
@@ -80,7 +89,8 @@ export interface ComponentModel {
80
89
  name: string;
81
90
  description: string | null;
82
91
  isReadme: boolean;
83
- examples: ExampleModel[];
92
+ see: string[];
93
+ security: string[];
84
94
  modulePath: string;
85
95
  sourceLocation: SourceLocationModel;
86
96
  exportPaths: string[];
@@ -89,6 +99,8 @@ export interface ComponentModel {
89
99
  interface SourceFunctionModel {
90
100
  name: string;
91
101
  description: string | null;
102
+ see: string[];
103
+ security: string[];
92
104
  sourceLocation: SourceLocationModel;
93
105
  }
94
106
  export interface SequenceScenarioModel {
@@ -105,11 +117,6 @@ export interface ModuleModel {
105
117
  dependencies: string[];
106
118
  exports: string[];
107
119
  }
108
- interface ExampleModel {
109
- title: string | null;
110
- language: string | null;
111
- code: string;
112
- }
113
120
  interface SourceLocationModel {
114
121
  filePath: string;
115
122
  line: number;
@@ -1,4 +1,4 @@
1
- import type { ParadoxConfig } from '../config/types.js';
1
+ import type { ParadoxConfig } from '../types/config.js';
2
2
  /***
3
3
  * Searches upward from a start directory until it finds a supported Paradox config file.
4
4
  */
@@ -1,3 +1,4 @@
1
+ import { toFileStem } from '../toFileStem.js';
1
2
  const MAX_SEQUENCE_CALL_EDGES = 12;
2
3
  const MAX_SEQUENCE_PARTICIPANTS = 8;
3
4
  const MAX_BIN_SEQUENCE_PARTICIPANTS = 12;
@@ -193,13 +194,6 @@ function renderFallbackEdge(modules, prefix) {
193
194
  function uniqueSorted(values) {
194
195
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
195
196
  }
196
- function toFileStem(value) {
197
- return value
198
- .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
199
- .replace(/[^A-Za-z0-9]+/g, '-')
200
- .replace(/^-+|-+$/g, '')
201
- .toLowerCase();
202
- }
203
197
  function toMermaidId(value) {
204
198
  return value.replace(/[^A-Za-z0-9_]/g, '_');
205
199
  }