cgraphx 1.2.0 → 1.3.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 (136) hide show
  1. package/dist/.claude-template/hooks/precommit-check/precommit-check.cjs +90 -0
  2. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +99 -78
  3. package/dist/.claude-template/skills/precommit-review/SKILL.md +50 -0
  4. package/dist/.claude-template/skills/run-api-test/SKILL.md +187 -0
  5. package/dist/.claude-template/skills/run-api-test/assets/template-test-report.md +103 -0
  6. package/dist/.claude-template/skills/run-api-test/assets/template-test-verify.jsonl +5 -0
  7. package/dist/.claude-template/skills/run-api-test/references/bru-run.md +60 -0
  8. package/dist/.claude-template/skills/run-api-test/references/db-verification.md +81 -0
  9. package/dist/.claude-template/skills/run-api-test/references/report-format.md +104 -0
  10. package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +61 -0
  11. package/dist/.claude-template/skills/run-api-test/references/test-scope.md +64 -0
  12. package/dist/.claude-template/skills/write-api/SKILL.md +150 -0
  13. package/dist/.claude-template/skills/write-api/assets/template-api-spec.md +112 -0
  14. package/dist/.claude-template/skills/write-api/assets/template-request.bru +75 -0
  15. package/dist/.claude-template/skills/write-api/references/ai-prompts.md +133 -0
  16. package/dist/.claude-template/skills/write-api/references/api-spec-format.md +108 -0
  17. package/dist/.claude-template/skills/write-api/references/bru-format.md +144 -0
  18. package/dist/.claude-template/skills/write-api/references/collection-layout.md +81 -0
  19. package/dist/.claude-template/skills/write-api/references/environment-setup.md +105 -0
  20. package/dist/.claude-template/skills/write-api/references/interface-scope.md +74 -0
  21. package/dist/api-test/ai-fields.d.ts +37 -0
  22. package/dist/api-test/ai-fields.d.ts.map +1 -0
  23. package/dist/api-test/ai-fields.js +114 -0
  24. package/dist/api-test/ai-fields.js.map +1 -0
  25. package/dist/api-test/assemble.d.ts +76 -0
  26. package/dist/api-test/assemble.d.ts.map +1 -0
  27. package/dist/api-test/assemble.js +185 -0
  28. package/dist/api-test/assemble.js.map +1 -0
  29. package/dist/api-test/bru-cli-invoker.d.ts +72 -0
  30. package/dist/api-test/bru-cli-invoker.d.ts.map +1 -0
  31. package/dist/api-test/bru-cli-invoker.js +169 -0
  32. package/dist/api-test/bru-cli-invoker.js.map +1 -0
  33. package/dist/api-test/bru-report-parser.d.ts +24 -0
  34. package/dist/api-test/bru-report-parser.d.ts.map +1 -0
  35. package/dist/api-test/bru-report-parser.js +110 -0
  36. package/dist/api-test/bru-report-parser.js.map +1 -0
  37. package/dist/api-test/bru-runner.d.ts +101 -0
  38. package/dist/api-test/bru-runner.d.ts.map +1 -0
  39. package/dist/api-test/bru-runner.js +316 -0
  40. package/dist/api-test/bru-runner.js.map +1 -0
  41. package/dist/api-test/bru-writer.d.ts +52 -0
  42. package/dist/api-test/bru-writer.d.ts.map +1 -0
  43. package/dist/api-test/bru-writer.js +159 -0
  44. package/dist/api-test/bru-writer.js.map +1 -0
  45. package/dist/api-test/call-chain-extractor.d.ts +80 -0
  46. package/dist/api-test/call-chain-extractor.d.ts.map +1 -0
  47. package/dist/api-test/call-chain-extractor.js +179 -0
  48. package/dist/api-test/call-chain-extractor.js.map +1 -0
  49. package/dist/api-test/cli.d.ts +133 -0
  50. package/dist/api-test/cli.d.ts.map +1 -0
  51. package/dist/api-test/cli.js +1009 -0
  52. package/dist/api-test/cli.js.map +1 -0
  53. package/dist/api-test/config.d.ts +75 -0
  54. package/dist/api-test/config.d.ts.map +1 -0
  55. package/dist/api-test/config.js +406 -0
  56. package/dist/api-test/config.js.map +1 -0
  57. package/dist/api-test/db-query-cli.d.ts +51 -0
  58. package/dist/api-test/db-query-cli.d.ts.map +1 -0
  59. package/dist/api-test/db-query-cli.js +119 -0
  60. package/dist/api-test/db-query-cli.js.map +1 -0
  61. package/dist/api-test/enhance-prepare.d.ts +111 -0
  62. package/dist/api-test/enhance-prepare.d.ts.map +1 -0
  63. package/dist/api-test/enhance-prepare.js +425 -0
  64. package/dist/api-test/enhance-prepare.js.map +1 -0
  65. package/dist/api-test/enhance-write.d.ts +28 -0
  66. package/dist/api-test/enhance-write.d.ts.map +1 -0
  67. package/dist/api-test/enhance-write.js +145 -0
  68. package/dist/api-test/enhance-write.js.map +1 -0
  69. package/dist/api-test/errors.d.ts +48 -0
  70. package/dist/api-test/errors.d.ts.map +1 -0
  71. package/dist/api-test/errors.js +76 -0
  72. package/dist/api-test/errors.js.map +1 -0
  73. package/dist/api-test/field-extractor.d.ts +98 -0
  74. package/dist/api-test/field-extractor.d.ts.map +1 -0
  75. package/dist/api-test/field-extractor.js +327 -0
  76. package/dist/api-test/field-extractor.js.map +1 -0
  77. package/dist/api-test/impl-finder.d.ts +37 -0
  78. package/dist/api-test/impl-finder.d.ts.map +1 -0
  79. package/dist/api-test/impl-finder.js +54 -0
  80. package/dist/api-test/impl-finder.js.map +1 -0
  81. package/dist/api-test/index.d.ts +41 -0
  82. package/dist/api-test/index.d.ts.map +1 -0
  83. package/dist/api-test/index.js +124 -0
  84. package/dist/api-test/index.js.map +1 -0
  85. package/dist/api-test/java-parser.d.ts +89 -0
  86. package/dist/api-test/java-parser.d.ts.map +1 -0
  87. package/dist/api-test/java-parser.js +508 -0
  88. package/dist/api-test/java-parser.js.map +1 -0
  89. package/dist/api-test/md-writer.d.ts +49 -0
  90. package/dist/api-test/md-writer.d.ts.map +1 -0
  91. package/dist/api-test/md-writer.js +202 -0
  92. package/dist/api-test/md-writer.js.map +1 -0
  93. package/dist/api-test/parser-httpservice.d.ts +91 -0
  94. package/dist/api-test/parser-httpservice.d.ts.map +1 -0
  95. package/dist/api-test/parser-httpservice.js +271 -0
  96. package/dist/api-test/parser-httpservice.js.map +1 -0
  97. package/dist/api-test/report.d.ts +188 -0
  98. package/dist/api-test/report.d.ts.map +1 -0
  99. package/dist/api-test/report.js +522 -0
  100. package/dist/api-test/report.js.map +1 -0
  101. package/dist/api-test/snapshot.d.ts +26 -0
  102. package/dist/api-test/snapshot.d.ts.map +1 -0
  103. package/dist/api-test/snapshot.js +150 -0
  104. package/dist/api-test/snapshot.js.map +1 -0
  105. package/dist/api-test/test-history.d.ts +48 -0
  106. package/dist/api-test/test-history.d.ts.map +1 -0
  107. package/dist/api-test/test-history.js +122 -0
  108. package/dist/api-test/test-history.js.map +1 -0
  109. package/dist/api-test/types.d.ts +174 -0
  110. package/dist/api-test/types.d.ts.map +1 -0
  111. package/dist/api-test/types.js +13 -0
  112. package/dist/api-test/types.js.map +1 -0
  113. package/dist/api-test/verify-prepare.d.ts +30 -0
  114. package/dist/api-test/verify-prepare.d.ts.map +1 -0
  115. package/dist/api-test/verify-prepare.js +150 -0
  116. package/dist/api-test/verify-prepare.js.map +1 -0
  117. package/dist/api-test/verify-write.d.ts +31 -0
  118. package/dist/api-test/verify-write.d.ts.map +1 -0
  119. package/dist/api-test/verify-write.js +159 -0
  120. package/dist/api-test/verify-write.js.map +1 -0
  121. package/dist/dbquery/dump-schema.d.ts +46 -0
  122. package/dist/dbquery/dump-schema.d.ts.map +1 -0
  123. package/dist/dbquery/dump-schema.js +379 -0
  124. package/dist/dbquery/dump-schema.js.map +1 -0
  125. package/dist/installer/targets/claude.d.ts +15 -0
  126. package/dist/installer/targets/claude.d.ts.map +1 -1
  127. package/dist/installer/targets/claude.js +53 -0
  128. package/dist/installer/targets/claude.js.map +1 -1
  129. package/package.json +1 -1
  130. package/scripts/agent-eval/block-cgraphx-and-gitnexus-cli-hook.sh +0 -43
  131. package/scripts/agent-eval/block-cgraphx-cli-hook.sh +0 -32
  132. package/scripts/agent-eval/block-cgraphx-cli-settings.json +0 -16
  133. package/scripts/agent-eval/cli-vs-mcp-3arm.sh +0 -121
  134. package/scripts/agent-eval/multi-tool-eval.sh +0 -171
  135. package/scripts/agent-eval/parse-cli-vs-mcp.mjs +0 -232
  136. package/scripts/agent-eval/parse-multi-tool.mjs +0 -242
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Markdown `.md` file writer — frontmatter (YAML) + body.
3
+ *
4
+ * Spec §5.3 frontmatter schema. The Endpoint type uses camelCase
5
+ * (`svcId`, `urlPattern`, `httpMethod`, `interfaceFqn`, `skipReason`,
6
+ * `authRequired`, `depTables`, `callChain`, `paramIndex`, `javaType`,
7
+ * `sourceTable`, `sourceColumn`, `sourceFilter`, `fixtureOnly`, `bruPath`,
8
+ * `mdPath`). The frontmatter uses snake_case. This module owns the
9
+ * camelCase → snake_case conversion in both directions (write here, read
10
+ * back in a future parser).
11
+ *
12
+ * Scan phase writes empty `fields: []`, `call_chain: []`, `dep_tables: []`
13
+ * — the analyze phase (T-30) fills them in.
14
+ *
15
+ * Public surface:
16
+ * - `renderMd(endpoint)` — string
17
+ * - `writeMd(endpoint, outputDir)` — Promise<string> (written path)
18
+ */
19
+ import type { Endpoint } from './types';
20
+ /** Filename for an endpoint's `.md` pair: `<svc_id>_<methodName>.md`. */
21
+ export declare function mdFileName(endpoint: Endpoint): string;
22
+ /** Subdirectory under `outputDir` for an endpoint's service: `<service>/`. */
23
+ export declare function serviceDirName(endpoint: Endpoint): string;
24
+ /** Convert a camelCase identifier to snake_case. */
25
+ export declare function camelToSnake(s: string): string;
26
+ /**
27
+ * Render the full `.md` body — frontmatter + sections. Scan phase leaves
28
+ * the fields/call_chain/dep_tables arrays empty and the 备注 section blank;
29
+ * downstream phases fill them in by re-rendering or by hand.
30
+ */
31
+ export declare function renderMd(endpoint: Endpoint): string;
32
+ /**
33
+ * Write an endpoint's `.md` to `<outputDir>/<service>/<svc_id>_<methodName>.md`.
34
+ * Creates the service directory if needed. Returns the absolute written path.
35
+ *
36
+ * Also stamps the written path back onto `endpoint.mdPath`.
37
+ */
38
+ export declare function writeMd(endpoint: Endpoint, outputDir: string): Promise<string>;
39
+ /** Format a string as a YAML scalar — quoted if it contains special chars. */
40
+ declare function yamlScalar(s: string): string;
41
+ /** Internal helpers re-exported for tests. */
42
+ export declare const __INTERNAL_MD: {
43
+ mdFileName: typeof mdFileName;
44
+ serviceDirName: typeof serviceDirName;
45
+ camelToSnake: typeof camelToSnake;
46
+ yamlScalar: typeof yamlScalar;
47
+ };
48
+ export {};
49
+ //# sourceMappingURL=md-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md-writer.d.ts","sourceRoot":"","sources":["../../src/api-test/md-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,SAAS,CAAC;AAE/C,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAErD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAEzD;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9C;AA6DD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAMnD;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAID,8EAA8E;AAC9E,iBAAS,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAQrC;AAqBD,8CAA8C;AAC9C,eAAO,MAAM,aAAa;;;;;CAKzB,CAAC"}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * Markdown `.md` file writer — frontmatter (YAML) + body.
4
+ *
5
+ * Spec §5.3 frontmatter schema. The Endpoint type uses camelCase
6
+ * (`svcId`, `urlPattern`, `httpMethod`, `interfaceFqn`, `skipReason`,
7
+ * `authRequired`, `depTables`, `callChain`, `paramIndex`, `javaType`,
8
+ * `sourceTable`, `sourceColumn`, `sourceFilter`, `fixtureOnly`, `bruPath`,
9
+ * `mdPath`). The frontmatter uses snake_case. This module owns the
10
+ * camelCase → snake_case conversion in both directions (write here, read
11
+ * back in a future parser).
12
+ *
13
+ * Scan phase writes empty `fields: []`, `call_chain: []`, `dep_tables: []`
14
+ * — the analyze phase (T-30) fills them in.
15
+ *
16
+ * Public surface:
17
+ * - `renderMd(endpoint)` — string
18
+ * - `writeMd(endpoint, outputDir)` — Promise<string> (written path)
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.__INTERNAL_MD = void 0;
55
+ exports.mdFileName = mdFileName;
56
+ exports.serviceDirName = serviceDirName;
57
+ exports.camelToSnake = camelToSnake;
58
+ exports.renderMd = renderMd;
59
+ exports.writeMd = writeMd;
60
+ const fs = __importStar(require("node:fs"));
61
+ const path = __importStar(require("node:path"));
62
+ /** Filename for an endpoint's `.md` pair: `<svc_id>_<methodName>.md`. */
63
+ function mdFileName(endpoint) {
64
+ return `${endpoint.svcId}_${endpoint.method}.md`;
65
+ }
66
+ /** Subdirectory under `outputDir` for an endpoint's service: `<service>/`. */
67
+ function serviceDirName(endpoint) {
68
+ return endpoint.service;
69
+ }
70
+ /** Convert a camelCase identifier to snake_case. */
71
+ function camelToSnake(s) {
72
+ // Handles consecutive capitals (e.g. `HTTPMethod` → `http_method`).
73
+ return s
74
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
75
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
76
+ .toLowerCase();
77
+ }
78
+ /**
79
+ * Build the frontmatter YAML block for an endpoint. camelCase → snake_case
80
+ * field names per spec §5.3.
81
+ */
82
+ function renderFrontmatter(endpoint) {
83
+ const lines = ['---'];
84
+ lines.push(`svc_id: ${yamlScalar(endpoint.svcId)}`);
85
+ lines.push(`service: ${yamlScalar(endpoint.service)}`);
86
+ lines.push(`interface_fqn: ${yamlScalar(endpoint.interfaceFqn)}`);
87
+ lines.push(`method: ${yamlScalar(endpoint.method)}`);
88
+ lines.push(`signature: ${yamlScalar(endpoint.signature)}`);
89
+ lines.push(`url_pattern: ${yamlScalar(endpoint.urlPattern)}`);
90
+ lines.push(`http_method: ${yamlScalar(endpoint.httpMethod)}`);
91
+ lines.push(`status: ${yamlScalar(endpoint.status)}`);
92
+ lines.push(`skip_reason: ${endpoint.skipReason === null ? 'null' : yamlScalar(endpoint.skipReason)}`);
93
+ lines.push(`auth_required: ${endpoint.authRequired}`);
94
+ // dep_tables: string[]
95
+ lines.push(`dep_tables: ${yamlStringArray(endpoint.depTables)}`);
96
+ // fields: [] in scan phase (analyze fills in)
97
+ lines.push(`fields: ${renderFieldsBlock(endpoint.fields)}`);
98
+ // call_chain: string[] (empty in scan phase)
99
+ lines.push(`call_chain: ${yamlStringArray(endpoint.callChain)}`);
100
+ // javadoc
101
+ lines.push(`javadoc: ${endpoint.javadoc === null ? 'null' : yamlBlock(endpoint.javadoc)}`);
102
+ lines.push(`notes: ${endpoint.notes === null ? 'null' : yamlBlock(endpoint.notes)}`);
103
+ // method_attr — nested object from `@MethodAttr` (camelCase→snake_case keys)
104
+ lines.push(`method_attr:`);
105
+ lines.push(` resolve_param: ${endpoint.methodAttr.resolveParam}`);
106
+ lines.push(` handle_return: ${endpoint.methodAttr.handleReturn}`);
107
+ lines.push(` open: ${endpoint.methodAttr.open}`);
108
+ // Optional path references — only emit when set (writeMd stamps them).
109
+ if (endpoint.bruPath) {
110
+ lines.push(`bru_path: ${yamlScalar(endpoint.bruPath)}`);
111
+ }
112
+ if (endpoint.mdPath) {
113
+ lines.push(`md_path: ${yamlScalar(endpoint.mdPath)}`);
114
+ }
115
+ lines.push('---');
116
+ return lines.join('\n');
117
+ }
118
+ /** Render the `fields:` block — either `[]` or a YAML list of field maps. */
119
+ function renderFieldsBlock(fields) {
120
+ if (fields.length === 0)
121
+ return '[]';
122
+ const lines = [];
123
+ for (const f of fields) {
124
+ lines.push(` - param_index: ${f.paramIndex}`);
125
+ lines.push(` name: ${yamlScalar(f.name)}`);
126
+ lines.push(` java_type: ${yamlScalar(f.javaType)}`);
127
+ lines.push(` source_table: ${f.sourceTable === null ? 'null' : yamlScalar(f.sourceTable)}`);
128
+ lines.push(` source_column: ${f.sourceColumn === null ? 'null' : yamlScalar(f.sourceColumn)}`);
129
+ lines.push(` source_filter: ${f.sourceFilter === null ? 'null' : yamlScalar(f.sourceFilter)}`);
130
+ lines.push(` literal: ${f.literal === null ? 'null' : yamlScalar(f.literal)}`);
131
+ lines.push(` fixture_only: ${f.fixtureOnly}`);
132
+ lines.push(` required: ${f.required}`);
133
+ }
134
+ return '\n' + lines.join('\n');
135
+ }
136
+ /**
137
+ * Render the full `.md` body — frontmatter + sections. Scan phase leaves
138
+ * the fields/call_chain/dep_tables arrays empty and the 备注 section blank;
139
+ * downstream phases fill them in by re-rendering or by hand.
140
+ */
141
+ function renderMd(endpoint) {
142
+ const fm = renderFrontmatter(endpoint);
143
+ const heading = `# ${endpoint.method} — ${endpoint.javadoc ? firstLine(endpoint.javadoc) : '(待补充业务说明)'}`;
144
+ const javadocSection = `## 业务说明(从 Javadoc)\n\n${endpoint.javadoc ?? '(scan 阶段未提取到 Javadoc)'}`;
145
+ const notesSection = `## 备注\n\n${endpoint.notes ?? ''}`;
146
+ return `${fm}\n\n${heading}\n\n${javadocSection}\n\n${notesSection}\n`;
147
+ }
148
+ /**
149
+ * Write an endpoint's `.md` to `<outputDir>/<service>/<svc_id>_<methodName>.md`.
150
+ * Creates the service directory if needed. Returns the absolute written path.
151
+ *
152
+ * Also stamps the written path back onto `endpoint.mdPath`.
153
+ */
154
+ async function writeMd(endpoint, outputDir) {
155
+ const serviceDir = path.join(outputDir, serviceDirName(endpoint));
156
+ await fs.promises.mkdir(serviceDir, { recursive: true });
157
+ const filePath = path.join(serviceDir, mdFileName(endpoint));
158
+ // Stamp mdPath onto the endpoint BEFORE rendering so the frontmatter can
159
+ // reference it (self-referential — but consistent with bru_path).
160
+ endpoint.mdPath = filePath;
161
+ const content = renderMd(endpoint);
162
+ await fs.promises.writeFile(filePath, content, 'utf8');
163
+ return filePath;
164
+ }
165
+ // ─── YAML scalar formatting helpers ────────────────────────────────────────
166
+ /** Format a string as a YAML scalar — quoted if it contains special chars. */
167
+ function yamlScalar(s) {
168
+ if (s === '')
169
+ return '""';
170
+ // Quote if the string contains any of: leading/trailing space, colon,
171
+ // hash, brace, bracket, comma, quote, newline, or looks like a number/bool/null.
172
+ const needsQuote = /[\s:#{}\[\],&*?|<>'"%@`]|^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(s)
173
+ || /^(true|false|null|yes|no|on|off)$/i.test(s);
174
+ if (!needsQuote)
175
+ return s;
176
+ return '"' + s.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
177
+ }
178
+ /** Format a string array — `[]` if empty, else a YAML block list. */
179
+ function yamlStringArray(arr) {
180
+ if (arr.length === 0)
181
+ return '[]';
182
+ return '\n' + arr.map((s) => ` - ${yamlScalar(s)}`).join('\n');
183
+ }
184
+ /** Format a multi-line string as a YAML literal block (|- / |). */
185
+ function yamlBlock(s) {
186
+ // Use the literal block style. Indent each line by 2 spaces.
187
+ const indented = s.split(/\r?\n/).map((line) => ` ${line}`).join('\n');
188
+ return `|-\n${indented}`;
189
+ }
190
+ /** First non-empty line of a javadoc string, trimmed. */
191
+ function firstLine(javadoc) {
192
+ const line = javadoc.split(/\r?\n/).map((s) => s.trim()).find((s) => s.length > 0);
193
+ return line ?? '';
194
+ }
195
+ /** Internal helpers re-exported for tests. */
196
+ exports.__INTERNAL_MD = {
197
+ mdFileName,
198
+ serviceDirName,
199
+ camelToSnake,
200
+ yamlScalar,
201
+ };
202
+ //# sourceMappingURL=md-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md-writer.js","sourceRoot":"","sources":["../../src/api-test/md-writer.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQH,gCAEC;AAGD,wCAEC;AAGD,oCAMC;AAkED,4BAMC;AAQD,0BAUC;AAhHD,4CAA8B;AAC9B,gDAAkC;AAIlC,yEAAyE;AACzE,SAAgB,UAAU,CAAC,QAAkB;IAC3C,OAAO,GAAG,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;AACnD,CAAC;AAED,8EAA8E;AAC9E,SAAgB,cAAc,CAAC,QAAkB;IAC/C,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC;AAED,oDAAoD;AACpD,SAAgB,YAAY,CAAC,CAAS;IACpC,oEAAoE;IACpE,OAAO,CAAC;SACL,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,QAAkB;IAC3C,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,kBAAkB,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,cAAc,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtG,KAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,uBAAuB;IACvB,KAAK,CAAC,IAAI,CAAC,eAAe,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACjE,8CAA8C;IAC9C,KAAK,CAAC,IAAI,CAAC,WAAW,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5D,6CAA6C;IAC7C,KAAK,CAAC,IAAI,CAAC,eAAe,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACjE,UAAU;IACV,KAAK,CAAC,IAAI,CAAC,YAAY,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3F,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrF,6EAA6E;IAC7E,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,QAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,oBAAoB,QAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,uEAAuE;IACvE,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,6EAA6E;AAC7E,SAAS,iBAAiB,CAAC,MAAe;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,kBAAkB,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC/F,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAClG,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAClG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAClF,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAgB,QAAQ,CAAC,QAAkB;IACzC,MAAM,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,KAAK,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACzG,MAAM,cAAc,GAAG,yBAAyB,QAAQ,CAAC,OAAO,IAAI,uBAAuB,EAAE,CAAC;IAC9F,MAAM,YAAY,GAAG,YAAY,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;IACxD,OAAO,GAAG,EAAE,OAAO,OAAO,OAAO,cAAc,OAAO,YAAY,IAAI,CAAC;AACzE,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,OAAO,CAAC,QAAkB,EAAE,SAAiB;IACjE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7D,yEAAyE;IACzE,kEAAkE;IAClE,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAE9E,8EAA8E;AAC9E,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1B,sEAAsE;IACtE,iFAAiF;IACjF,MAAM,UAAU,GAAG,kEAAkE,CAAC,IAAI,CAAC,CAAC,CAAC;WACxF,oCAAoC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC;AACnE,CAAC;AAED,qEAAqE;AACrE,SAAS,eAAe,CAAC,GAAa;IACpC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,mEAAmE;AACnE,SAAS,SAAS,CAAC,CAAS;IAC1B,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO,OAAO,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED,yDAAyD;AACzD,SAAS,SAAS,CAAC,OAAe;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnF,OAAO,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,8CAA8C;AACjC,QAAA,aAAa,GAAG;IAC3B,UAAU;IACV,cAAc;IACd,YAAY;IACZ,UAAU;CACX,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Scan phase — discover HTTP endpoints from Java source.
3
+ *
4
+ * Spec contract (T-20): walks every `.java` file under `projectRoot`,
5
+ * keeps interfaces annotated with `@Center` (provider side, FQN =
6
+ * `config.providerAnnotationFqn`), extracts one `Endpoint` per method,
7
+ * and computes the service-group name + URL pattern.
8
+ *
9
+ * Self-contained: depends only on `node:fs` / `node:path` +
10
+ * `./java-parser` (T-11) + `./types` + `./errors`. Does NOT call
11
+ * `codegraph_explore`, does NOT touch `src/extraction/` /
12
+ * `src/resolution/`, does NOT call db-query (that's the assemble phase).
13
+ *
14
+ * Annotation detection is SHALLOW — no recursive inheritance walk, no
15
+ * meta-annotation walk. `@RCenter` is intentionally NOT recognized.
16
+ *
17
+ * Public surface:
18
+ * - `scanEndpoints(projectRoot, config)` — Promise<Endpoint[]>
19
+ */
20
+ import type { ApiTestConfig, Endpoint } from './types';
21
+ import { type ClassInfo, type MethodSignature } from './java-parser';
22
+ /**
23
+ * Walk `projectRoot` and yield every `.java` file path. Symlinks are not
24
+ * followed. Common build output / dependency dirs are pruned.
25
+ */
26
+ declare function iterJavaFiles(root: string): IterableIterator<string>;
27
+ /**
28
+ * Resolve the service-group name for an interface's package.
29
+ *
30
+ * 1. Apply `config.serviceGroupingRegex` to the interface's package name;
31
+ * take capture group 1 as the key.
32
+ * 2. Look the key up in `config.serviceNameMap`; if missing, fall back to
33
+ * `<key>-service` (the same shape as the default map's values).
34
+ *
35
+ * Returns `null` if the regex doesn't match — the caller will skip the
36
+ * interface (with a warning) in that case.
37
+ */
38
+ declare function resolveServiceName(packageName: string, config: ApiTestConfig): string | null;
39
+ /** Build a method signature string, e.g. `Object qryOrderList(Object reqVo)`. */
40
+ declare function buildSignature(method: MethodSignature): string;
41
+ /**
42
+ * Extract the `@MethodAttr` annotation's three boolean attributes from a
43
+ * method's annotations. Matches by simple name `MethodAttr` (the hx
44
+ * convention — the FQN is config-driven elsewhere, but MethodAttr is matched
45
+ * by simple name like `@Center`). Defaults when the annotation is absent or
46
+ * an attribute is unset: resolveParam=true, handleReturn=false, open=true.
47
+ *
48
+ * The attribute values may be boolean literals (`true`/`false`) or unquoted
49
+ * identifiers; non-`false` values (including absent) resolve to the default.
50
+ */
51
+ declare function extractMethodAttr(method: MethodSignature): {
52
+ resolveParam: boolean;
53
+ handleReturn: boolean;
54
+ open: boolean;
55
+ };
56
+ /**
57
+ * Substitute `{{baseUrl}}` / `{service}` / `{svc_id}` / `{methodName}` in
58
+ * `config.urlTemplate`. The `{{baseUrl}}` placeholder is kept verbatim (it
59
+ * is resolved at request time from the profile); other tokens are filled in
60
+ * from the endpoint's static data.
61
+ */
62
+ declare function buildUrlPattern(config: ApiTestConfig, service: string, svcId: string, methodName: string): string;
63
+ /**
64
+ * Extract the `value` attribute of the `@Center` annotation on a class.
65
+ * Returns `null` when the annotation is absent or its value is empty.
66
+ *
67
+ * Matches by simple name against `config.providerAnnotationFqn` so a source
68
+ * `@Center("x")` matches the configured FQN
69
+ * `org.springframework.httpservice.annotation.Center`.
70
+ */
71
+ declare function extractSvcId(cls: ClassInfo, config: ApiTestConfig): string | null;
72
+ /**
73
+ * Scan every `.java` file under `projectRoot` and build an `Endpoint[]` —
74
+ * one entry per method declared on a `@Center`-annotated interface.
75
+ *
76
+ * Errors per file are caught and logged to stderr as warnings; a parse
77
+ * failure on one file does not abort the rest of the scan.
78
+ */
79
+ export declare function scanEndpoints(projectRoot: string, config: ApiTestConfig): Promise<Endpoint[]>;
80
+ /** Internal helpers re-exported for tests. */
81
+ export declare const __INTERNAL_SCAN: {
82
+ resolveServiceName: typeof resolveServiceName;
83
+ buildSignature: typeof buildSignature;
84
+ buildUrlPattern: typeof buildUrlPattern;
85
+ extractSvcId: typeof extractSvcId;
86
+ extractMethodAttr: typeof extractMethodAttr;
87
+ iterJavaFiles: typeof iterJavaFiles;
88
+ DEFAULT_IGNORE_DIRS: Set<string>;
89
+ };
90
+ export {};
91
+ //# sourceMappingURL=parser-httpservice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser-httpservice.d.ts","sourceRoot":"","sources":["../../src/api-test/parser-httpservice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAcpF;;;GAGG;AACH,iBAAU,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAmB9D;AAQD;;;;;;;;;;GAUG;AACH,iBAAS,kBAAkB,CACzB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB,MAAM,GAAG,IAAI,CAOf;AAED,iFAAiF;AACjF,iBAAS,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAGvD;AAED;;;;;;;;;GASG;AACH,iBAAS,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf,CASA;AAWD;;;;;GAKG;AACH,iBAAS,eAAe,CACtB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GACjB,MAAM,CAOR;AAED;;;;;;;GAOG;AACH,iBAAS,YAAY,CACnB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,aAAa,GACpB,MAAM,GAAG,IAAI,CASf;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,QAAQ,EAAE,CAAC,CA0DrB;AAED,8CAA8C;AAC9C,eAAO,MAAM,eAAe;;;;;;;;CAQ3B,CAAC"}
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /**
3
+ * Scan phase — discover HTTP endpoints from Java source.
4
+ *
5
+ * Spec contract (T-20): walks every `.java` file under `projectRoot`,
6
+ * keeps interfaces annotated with `@Center` (provider side, FQN =
7
+ * `config.providerAnnotationFqn`), extracts one `Endpoint` per method,
8
+ * and computes the service-group name + URL pattern.
9
+ *
10
+ * Self-contained: depends only on `node:fs` / `node:path` +
11
+ * `./java-parser` (T-11) + `./types` + `./errors`. Does NOT call
12
+ * `codegraph_explore`, does NOT touch `src/extraction/` /
13
+ * `src/resolution/`, does NOT call db-query (that's the assemble phase).
14
+ *
15
+ * Annotation detection is SHALLOW — no recursive inheritance walk, no
16
+ * meta-annotation walk. `@RCenter` is intentionally NOT recognized.
17
+ *
18
+ * Public surface:
19
+ * - `scanEndpoints(projectRoot, config)` — Promise<Endpoint[]>
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.__INTERNAL_SCAN = void 0;
56
+ exports.scanEndpoints = scanEndpoints;
57
+ const fs = __importStar(require("node:fs"));
58
+ const path = __importStar(require("node:path"));
59
+ const java_parser_1 = require("./java-parser");
60
+ const errors_1 = require("./errors");
61
+ /** Default ignore list — node_modules / dist / build outputs / hidden dirs. */
62
+ const DEFAULT_IGNORE_DIRS = new Set([
63
+ 'node_modules',
64
+ 'dist',
65
+ 'build',
66
+ 'target',
67
+ 'out',
68
+ '.git',
69
+ '.cgraphx',
70
+ ]);
71
+ /**
72
+ * Walk `projectRoot` and yield every `.java` file path. Symlinks are not
73
+ * followed. Common build output / dependency dirs are pruned.
74
+ */
75
+ function* iterJavaFiles(root) {
76
+ let entries;
77
+ try {
78
+ entries = fs.readdirSync(root, { withFileTypes: true });
79
+ }
80
+ catch {
81
+ return;
82
+ }
83
+ for (const entry of entries) {
84
+ if (entry.name.startsWith('.')) {
85
+ // Hidden dirs (e.g. .git, .cgraphx) — skip but allow hidden files.
86
+ if (entry.isDirectory())
87
+ continue;
88
+ }
89
+ if (entry.isDirectory()) {
90
+ if (DEFAULT_IGNORE_DIRS.has(entry.name))
91
+ continue;
92
+ yield* iterJavaFiles(path.join(root, entry.name));
93
+ }
94
+ else if (entry.isFile() && entry.name.endsWith('.java')) {
95
+ yield path.join(root, entry.name);
96
+ }
97
+ }
98
+ }
99
+ /** Simple (last segment) name of a possibly-qualified identifier. */
100
+ function simpleName(fqnOrSimple) {
101
+ const last = fqnOrSimple.split('.').pop();
102
+ return last;
103
+ }
104
+ /**
105
+ * Resolve the service-group name for an interface's package.
106
+ *
107
+ * 1. Apply `config.serviceGroupingRegex` to the interface's package name;
108
+ * take capture group 1 as the key.
109
+ * 2. Look the key up in `config.serviceNameMap`; if missing, fall back to
110
+ * `<key>-service` (the same shape as the default map's values).
111
+ *
112
+ * Returns `null` if the regex doesn't match — the caller will skip the
113
+ * interface (with a warning) in that case.
114
+ */
115
+ function resolveServiceName(packageName, config) {
116
+ const re = new RegExp(config.serviceGroupingRegex);
117
+ const m = re.exec(packageName);
118
+ if (!m)
119
+ return null;
120
+ const key = m[1] ?? m[0];
121
+ if (!key)
122
+ return null;
123
+ return config.serviceNameMap[key] ?? `${key}-service`;
124
+ }
125
+ /** Build a method signature string, e.g. `Object qryOrderList(Object reqVo)`. */
126
+ function buildSignature(method) {
127
+ const params = method.parameters.map((p) => `${p.type} ${p.name}`).join(', ');
128
+ return `${method.returnType} ${method.name}(${params})`;
129
+ }
130
+ /**
131
+ * Extract the `@MethodAttr` annotation's three boolean attributes from a
132
+ * method's annotations. Matches by simple name `MethodAttr` (the hx
133
+ * convention — the FQN is config-driven elsewhere, but MethodAttr is matched
134
+ * by simple name like `@Center`). Defaults when the annotation is absent or
135
+ * an attribute is unset: resolveParam=true, handleReturn=false, open=true.
136
+ *
137
+ * The attribute values may be boolean literals (`true`/`false`) or unquoted
138
+ * identifiers; non-`false` values (including absent) resolve to the default.
139
+ */
140
+ function extractMethodAttr(method) {
141
+ const defaults = { resolveParam: true, handleReturn: false, open: true };
142
+ const ann = method.annotations.find((a) => simpleName(a.fqn) === 'MethodAttr');
143
+ if (!ann)
144
+ return defaults;
145
+ return {
146
+ resolveParam: parseBoolAttr(ann.attributes.resolveParam, defaults.resolveParam),
147
+ handleReturn: parseBoolAttr(ann.attributes.handleReturn, defaults.handleReturn),
148
+ open: parseBoolAttr(ann.attributes.open, defaults.open),
149
+ };
150
+ }
151
+ /** Parse an annotation attribute value as a boolean. `false` → false; anything else falls back to the default. */
152
+ function parseBoolAttr(value, fallback) {
153
+ if (value === undefined || value === '')
154
+ return fallback;
155
+ const v = value.trim().toLowerCase();
156
+ if (v === 'false')
157
+ return false;
158
+ if (v === 'true')
159
+ return true;
160
+ return fallback;
161
+ }
162
+ /**
163
+ * Substitute `{{baseUrl}}` / `{service}` / `{svc_id}` / `{methodName}` in
164
+ * `config.urlTemplate`. The `{{baseUrl}}` placeholder is kept verbatim (it
165
+ * is resolved at request time from the profile); other tokens are filled in
166
+ * from the endpoint's static data.
167
+ */
168
+ function buildUrlPattern(config, service, svcId, methodName) {
169
+ const pathSegment = config.serviceUrlPaths?.[service] ?? 'service';
170
+ return config.urlTemplate
171
+ .replace(/\{service\}/g, service)
172
+ .replace(/\{pathSegment\}/g, pathSegment)
173
+ .replace(/\{svc_id\}/g, svcId)
174
+ .replace(/\{methodName\}/g, methodName);
175
+ }
176
+ /**
177
+ * Extract the `value` attribute of the `@Center` annotation on a class.
178
+ * Returns `null` when the annotation is absent or its value is empty.
179
+ *
180
+ * Matches by simple name against `config.providerAnnotationFqn` so a source
181
+ * `@Center("x")` matches the configured FQN
182
+ * `org.springframework.httpservice.annotation.Center`.
183
+ */
184
+ function extractSvcId(cls, config) {
185
+ const targetSimple = simpleName(config.providerAnnotationFqn);
186
+ for (const ann of cls.annotations) {
187
+ if (simpleName(ann.fqn) !== targetSimple)
188
+ continue;
189
+ const v = ann.attributes['value'] ?? ann.attributes['id'] ?? '';
190
+ if (!v)
191
+ return null;
192
+ return v;
193
+ }
194
+ return null;
195
+ }
196
+ /**
197
+ * Scan every `.java` file under `projectRoot` and build an `Endpoint[]` —
198
+ * one entry per method declared on a `@Center`-annotated interface.
199
+ *
200
+ * Errors per file are caught and logged to stderr as warnings; a parse
201
+ * failure on one file does not abort the rest of the scan.
202
+ */
203
+ async function scanEndpoints(projectRoot, config) {
204
+ const endpoints = [];
205
+ for (const javaFile of iterJavaFiles(projectRoot)) {
206
+ let classes;
207
+ try {
208
+ classes = await (0, java_parser_1.parseJavaFile)(javaFile);
209
+ }
210
+ catch (err) {
211
+ const msg = err instanceof Error ? err.message : String(err);
212
+ process.stderr.write(`[api-test] warning: failed to parse ${javaFile}: ${msg}\n`);
213
+ continue;
214
+ }
215
+ for (const cls of classes) {
216
+ if (!cls.isInterface)
217
+ continue;
218
+ const svcId = extractSvcId(cls, config);
219
+ if (!svcId)
220
+ continue; // not a provider interface (or empty @Center value)
221
+ const service = resolveServiceName(cls.packageName, config);
222
+ if (!service) {
223
+ process.stderr.write(`[api-test] warning: interface ${cls.fqn} in package "${cls.packageName}" did not match serviceGroupingRegex; skipping.\n`);
224
+ continue;
225
+ }
226
+ for (const method of cls.methods) {
227
+ // Skip static initializers / synthetic bridge methods — interfaces
228
+ // only declare abstract methods, but a default method would carry a
229
+ // body; include them too, the analyzer can still skip later.
230
+ const signature = buildSignature(method);
231
+ const urlPattern = buildUrlPattern(config, service, svcId, method.name);
232
+ const methodAttr = extractMethodAttr(method);
233
+ endpoints.push({
234
+ svcId,
235
+ service,
236
+ interfaceFqn: cls.fqn,
237
+ method: method.name,
238
+ signature,
239
+ urlPattern,
240
+ httpMethod: config.defaultHttpMethod,
241
+ status: 'active',
242
+ skipReason: null,
243
+ authRequired: true,
244
+ depTables: [],
245
+ fields: [],
246
+ callChain: [],
247
+ javadoc: method.javadoc,
248
+ notes: null,
249
+ methodAttr,
250
+ bruPath: '', // filled by writeBru
251
+ mdPath: '', // filled by writeMd
252
+ });
253
+ }
254
+ }
255
+ }
256
+ return endpoints;
257
+ }
258
+ /** Internal helpers re-exported for tests. */
259
+ exports.__INTERNAL_SCAN = {
260
+ resolveServiceName,
261
+ buildSignature,
262
+ buildUrlPattern,
263
+ extractSvcId,
264
+ extractMethodAttr,
265
+ iterJavaFiles,
266
+ DEFAULT_IGNORE_DIRS,
267
+ };
268
+ // `ParseError` import kept for re-export / future use by callers that want
269
+ // to instanceof-check parser failures caught here and re-thrown elsewhere.
270
+ void errors_1.ParseError;
271
+ //# sourceMappingURL=parser-httpservice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser-httpservice.js","sourceRoot":"","sources":["../../src/api-test/parser-httpservice.ts"],"names":[],"mappings":"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"}