@planu/cli 0.28.0 → 0.29.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.
- package/dist/config/model-routing-rules.json +98 -0
- package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -1
- package/dist/engine/ai-cost-estimator/core.js +2 -202
- package/dist/engine/ai-cost-estimator/core.js.map +1 -1
- package/dist/engine/ai-cost-estimator/recommender.d.ts +8 -0
- package/dist/engine/ai-cost-estimator/recommender.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/recommender.js +94 -0
- package/dist/engine/ai-cost-estimator/recommender.js.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts +13 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js +102 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js.map +1 -0
- package/dist/engine/code-transforms/transform-engine.d.ts +7 -0
- package/dist/engine/code-transforms/transform-engine.d.ts.map +1 -0
- package/dist/engine/code-transforms/transform-engine.js +67 -0
- package/dist/engine/code-transforms/transform-engine.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js +92 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js +83 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.js +182 -0
- package/dist/engine/code-transforms/typescript/add-types.js.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts +38 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js +90 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js +103 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js +213 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts +8 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js +40 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js.map +1 -0
- package/dist/engine/mermaid/core.d.ts +18 -0
- package/dist/engine/mermaid/core.d.ts.map +1 -0
- package/dist/engine/mermaid/core.js +88 -0
- package/dist/engine/mermaid/core.js.map +1 -0
- package/dist/engine/mermaid/diagram-generators.d.ts +22 -0
- package/dist/engine/mermaid/diagram-generators.d.ts.map +1 -0
- package/dist/engine/mermaid/diagram-generators.js +139 -0
- package/dist/engine/mermaid/diagram-generators.js.map +1 -0
- package/dist/engine/mermaid/helpers.d.ts +8 -0
- package/dist/engine/mermaid/helpers.d.ts.map +1 -0
- package/dist/engine/mermaid/helpers.js +61 -0
- package/dist/engine/mermaid/helpers.js.map +1 -0
- package/dist/engine/mermaid-generator.d.ts +2 -37
- package/dist/engine/mermaid-generator.d.ts.map +1 -1
- package/dist/engine/mermaid-generator.js +4 -276
- package/dist/engine/mermaid-generator.js.map +1 -1
- package/dist/engine/model-router/complexity-analyzer.d.ts +26 -0
- package/dist/engine/model-router/complexity-analyzer.d.ts.map +1 -0
- package/dist/engine/model-router/complexity-analyzer.js +182 -0
- package/dist/engine/model-router/complexity-analyzer.js.map +1 -0
- package/dist/engine/model-router/cost-estimator.d.ts +6 -0
- package/dist/engine/model-router/cost-estimator.d.ts.map +1 -0
- package/dist/engine/model-router/cost-estimator.js +60 -0
- package/dist/engine/model-router/cost-estimator.js.map +1 -0
- package/dist/engine/model-router/historical-learner.d.ts +26 -0
- package/dist/engine/model-router/historical-learner.d.ts.map +1 -0
- package/dist/engine/model-router/historical-learner.js +91 -0
- package/dist/engine/model-router/historical-learner.js.map +1 -0
- package/dist/engine/model-router/rules-engine.d.ts +13 -0
- package/dist/engine/model-router/rules-engine.d.ts.map +1 -0
- package/dist/engine/model-router/rules-engine.js +142 -0
- package/dist/engine/model-router/rules-engine.js.map +1 -0
- package/dist/engine/spec-coverage/criteria-mapper.d.ts +1 -2
- package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -1
- package/dist/engine/spec-coverage/criteria-mapper.js +4 -203
- package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -1
- package/dist/engine/spec-coverage/keyword-extractor.d.ts +10 -0
- package/dist/engine/spec-coverage/keyword-extractor.d.ts.map +1 -0
- package/dist/engine/spec-coverage/keyword-extractor.js +147 -0
- package/dist/engine/spec-coverage/keyword-extractor.js.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts +9 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.js +59 -0
- package/dist/engine/spec-coverage/test-matchers.js.map +1 -0
- package/dist/engine/spec-templates/catalog-extra.d.ts +1 -1
- package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog-extra.js +8 -363
- package/dist/engine/spec-templates/catalog-extra.js.map +1 -1
- package/dist/engine/spec-templates/catalog.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog.js +10 -381
- package/dist/engine/spec-templates/catalog.js.map +1 -1
- package/dist/engine/spec-templates/templates-api-ui.d.ts +6 -0
- package/dist/engine/spec-templates/templates-api-ui.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-api-ui.js +188 -0
- package/dist/engine/spec-templates/templates-api-ui.js.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts +6 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.js +198 -0
- package/dist/engine/spec-templates/templates-auth-crud.js.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts +6 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.js +172 -0
- package/dist/engine/spec-templates/templates-data-security.js.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts +6 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.js +199 -0
- package/dist/engine/spec-templates/templates-perf-integration.js.map +1 -0
- package/dist/engine/vector-store/hnsw.d.ts +37 -0
- package/dist/engine/vector-store/hnsw.d.ts.map +1 -0
- package/dist/engine/vector-store/hnsw.js +294 -0
- package/dist/engine/vector-store/hnsw.js.map +1 -0
- package/dist/engine/vector-store/similarity.d.ts +21 -0
- package/dist/engine/vector-store/similarity.d.ts.map +1 -0
- package/dist/engine/vector-store/similarity.js +86 -0
- package/dist/engine/vector-store/similarity.js.map +1 -0
- package/dist/engine/vector-store/tfidf.d.ts +35 -0
- package/dist/engine/vector-store/tfidf.d.ts.map +1 -0
- package/dist/engine/vector-store/tfidf.js +255 -0
- package/dist/engine/vector-store/tfidf.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/vector-store/backend-factory.d.ts +9 -0
- package/dist/storage/vector-store/backend-factory.d.ts.map +1 -0
- package/dist/storage/vector-store/backend-factory.js +33 -0
- package/dist/storage/vector-store/backend-factory.js.map +1 -0
- package/dist/storage/vector-store/json-fallback.d.ts +21 -0
- package/dist/storage/vector-store/json-fallback.d.ts.map +1 -0
- package/dist/storage/vector-store/json-fallback.js +85 -0
- package/dist/storage/vector-store/json-fallback.js.map +1 -0
- package/dist/storage/vector-store/migrator.d.ts +10 -0
- package/dist/storage/vector-store/migrator.d.ts.map +1 -0
- package/dist/storage/vector-store/migrator.js +139 -0
- package/dist/storage/vector-store/migrator.js.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts +28 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.js +142 -0
- package/dist/storage/vector-store/sqlite-adapter.js.map +1 -0
- package/dist/tools/create-spec/constitution-validator.d.ts +4 -0
- package/dist/tools/create-spec/constitution-validator.d.ts.map +1 -0
- package/dist/tools/create-spec/constitution-validator.js +37 -0
- package/dist/tools/create-spec/constitution-validator.js.map +1 -0
- package/dist/tools/create-spec/post-creation.d.ts +11 -0
- package/dist/tools/create-spec/post-creation.d.ts.map +1 -0
- package/dist/tools/create-spec/post-creation.js +48 -0
- package/dist/tools/create-spec/post-creation.js.map +1 -0
- package/dist/tools/create-spec/spec-builder.d.ts +14 -0
- package/dist/tools/create-spec/spec-builder.d.ts.map +1 -0
- package/dist/tools/create-spec/spec-builder.js +131 -0
- package/dist/tools/create-spec/spec-builder.js.map +1 -0
- package/dist/tools/create-spec.d.ts.map +1 -1
- package/dist/tools/create-spec.js +42 -172
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/recommend-model-handler.d.ts +8 -0
- package/dist/tools/recommend-model-handler.d.ts.map +1 -0
- package/dist/tools/recommend-model-handler.js +65 -0
- package/dist/tools/recommend-model-handler.js.map +1 -0
- package/dist/tools/register-model-tools.d.ts +3 -0
- package/dist/tools/register-model-tools.d.ts.map +1 -0
- package/dist/tools/register-model-tools.js +50 -0
- package/dist/tools/register-model-tools.js.map +1 -0
- package/dist/tools/register-search-tools.d.ts +7 -0
- package/dist/tools/register-search-tools.d.ts.map +1 -0
- package/dist/tools/register-search-tools.js +34 -0
- package/dist/tools/register-search-tools.js.map +1 -0
- package/dist/tools/register-transform-tools.d.ts +3 -0
- package/dist/tools/register-transform-tools.d.ts.map +1 -0
- package/dist/tools/register-transform-tools.js +29 -0
- package/dist/tools/register-transform-tools.js.map +1 -0
- package/dist/tools/semantic-search-handler.d.ts +7 -0
- package/dist/tools/semantic-search-handler.d.ts.map +1 -0
- package/dist/tools/semantic-search-handler.js +72 -0
- package/dist/tools/semantic-search-handler.js.map +1 -0
- package/dist/tools/transform-code-handler.d.ts +7 -0
- package/dist/tools/transform-code-handler.d.ts.map +1 -0
- package/dist/tools/transform-code-handler.js +58 -0
- package/dist/tools/transform-code-handler.js.map +1 -0
- package/dist/types/advanced-framework.d.ts +47 -0
- package/dist/types/advanced-framework.d.ts.map +1 -0
- package/dist/types/advanced-framework.js +3 -0
- package/dist/types/advanced-framework.js.map +1 -0
- package/dist/types/code-transforms.d.ts +114 -0
- package/dist/types/code-transforms.d.ts.map +1 -0
- package/dist/types/code-transforms.js +11 -0
- package/dist/types/code-transforms.js.map +1 -0
- package/dist/types/css-framework.d.ts +110 -0
- package/dist/types/css-framework.d.ts.map +1 -0
- package/dist/types/css-framework.js +3 -0
- package/dist/types/css-framework.js.map +1 -0
- package/dist/types/dashboard.d.ts +77 -0
- package/dist/types/dashboard.d.ts.map +1 -0
- package/dist/types/dashboard.js +2 -0
- package/dist/types/dashboard.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/model-routing.d.ts +127 -0
- package/dist/types/model-routing.d.ts.map +1 -0
- package/dist/types/model-routing.js +3 -0
- package/dist/types/model-routing.js.map +1 -0
- package/dist/types/spec/core.d.ts +28 -1
- package/dist/types/spec/core.d.ts.map +1 -1
- package/dist/types/spec/inputs.d.ts +1 -6
- package/dist/types/spec/inputs.d.ts.map +1 -1
- package/dist/types/ui.d.ts +3 -231
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/ui.js +7 -1
- package/dist/types/ui.js.map +1 -1
- package/dist/types/vector-store.d.ts +137 -0
- package/dist/types/vector-store.d.ts.map +1 -0
- package/dist/types/vector-store.js +3 -0
- package/dist/types/vector-store.js.map +1 -0
- package/package.json +1 -1
- package/src/config/model-routing-rules.json +98 -0
|
@@ -1,78 +1,9 @@
|
|
|
1
1
|
// engine/spec-coverage/criteria-mapper.ts — Extracts acceptance criteria from
|
|
2
2
|
// HU.md and maps test files to each criterion using 3 strategies.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
'the',
|
|
8
|
-
'a',
|
|
9
|
-
'an',
|
|
10
|
-
'is',
|
|
11
|
-
'are',
|
|
12
|
-
'was',
|
|
13
|
-
'were',
|
|
14
|
-
'be',
|
|
15
|
-
'been',
|
|
16
|
-
'being',
|
|
17
|
-
'have',
|
|
18
|
-
'has',
|
|
19
|
-
'had',
|
|
20
|
-
'do',
|
|
21
|
-
'does',
|
|
22
|
-
'did',
|
|
23
|
-
'will',
|
|
24
|
-
'would',
|
|
25
|
-
'could',
|
|
26
|
-
'should',
|
|
27
|
-
'may',
|
|
28
|
-
'might',
|
|
29
|
-
'shall',
|
|
30
|
-
'must',
|
|
31
|
-
'can',
|
|
32
|
-
'to',
|
|
33
|
-
'of',
|
|
34
|
-
'in',
|
|
35
|
-
'on',
|
|
36
|
-
'at',
|
|
37
|
-
'by',
|
|
38
|
-
'for',
|
|
39
|
-
'with',
|
|
40
|
-
'from',
|
|
41
|
-
'as',
|
|
42
|
-
'and',
|
|
43
|
-
'or',
|
|
44
|
-
'but',
|
|
45
|
-
'not',
|
|
46
|
-
'no',
|
|
47
|
-
'if',
|
|
48
|
-
'when',
|
|
49
|
-
'where',
|
|
50
|
-
'that',
|
|
51
|
-
'which',
|
|
52
|
-
'this',
|
|
53
|
-
'it',
|
|
54
|
-
'its',
|
|
55
|
-
'el',
|
|
56
|
-
'la',
|
|
57
|
-
'los',
|
|
58
|
-
'las',
|
|
59
|
-
'un',
|
|
60
|
-
'una',
|
|
61
|
-
'de',
|
|
62
|
-
'del',
|
|
63
|
-
'en',
|
|
64
|
-
'que',
|
|
65
|
-
'se',
|
|
66
|
-
'por',
|
|
67
|
-
'para',
|
|
68
|
-
'con',
|
|
69
|
-
'al',
|
|
70
|
-
'lo',
|
|
71
|
-
'le',
|
|
72
|
-
'les',
|
|
73
|
-
'y',
|
|
74
|
-
'o',
|
|
75
|
-
]);
|
|
3
|
+
import { findDirectReferences, findSpecReferences, findKeywordMatches } from './test-matchers.js';
|
|
4
|
+
import { extractKeywords } from './keyword-extractor.js';
|
|
5
|
+
// Re-export for backward compatibility
|
|
6
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
76
7
|
// ---------------------------------------------------------------------------
|
|
77
8
|
// AC extraction
|
|
78
9
|
// ---------------------------------------------------------------------------
|
|
@@ -152,136 +83,6 @@ export function mapTestsToCriterion(criterion, testFiles, testContents, specId)
|
|
|
152
83
|
};
|
|
153
84
|
}
|
|
154
85
|
// ---------------------------------------------------------------------------
|
|
155
|
-
// Strategy implementations
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
158
|
-
function findDirectReferences(acId, testFiles, testContents) {
|
|
159
|
-
const matches = [];
|
|
160
|
-
// Build regex variants: AC-01, AC01, #AC-01, AC 01
|
|
161
|
-
const acNum = acId.replace('AC-', '');
|
|
162
|
-
const pattern = new RegExp(`\\b(?:AC[-\\s]?${acNum}|#AC-?${acNum})\\b`, 'i');
|
|
163
|
-
for (const tf of testFiles) {
|
|
164
|
-
const content = testContents.get(tf.file) ?? '';
|
|
165
|
-
if (!pattern.test(content)) {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
// Extract the test name from the first matching line
|
|
169
|
-
const testName = extractTestName(content, pattern);
|
|
170
|
-
matches.push({ file: tf.file, testName, strategy: 'direct-reference' });
|
|
171
|
-
}
|
|
172
|
-
return matches;
|
|
173
|
-
}
|
|
174
|
-
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
175
|
-
function findSpecReferences(specId, testFiles, testContents) {
|
|
176
|
-
const matches = [];
|
|
177
|
-
const specPattern = new RegExp(`\\b${specId.replace('-', '[-_]?')}\\b`, 'i');
|
|
178
|
-
for (const tf of testFiles) {
|
|
179
|
-
const inPath = specPattern.test(tf.file);
|
|
180
|
-
const content = testContents.get(tf.file) ?? '';
|
|
181
|
-
const inContent = specPattern.test(content);
|
|
182
|
-
if (!inPath && !inContent) {
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
const testName = inContent ? extractTestName(content, specPattern) : tf.file;
|
|
186
|
-
matches.push({ file: tf.file, testName, strategy: 'spec-reference' });
|
|
187
|
-
}
|
|
188
|
-
return matches;
|
|
189
|
-
}
|
|
190
|
-
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
191
|
-
function findKeywordMatches(keywords, testFiles, testContents) {
|
|
192
|
-
const matches = [];
|
|
193
|
-
for (const tf of testFiles) {
|
|
194
|
-
const content = testContents.get(tf.file) ?? '';
|
|
195
|
-
// Extract all describe/it/test block names
|
|
196
|
-
const testNames = extractAllTestNames(content);
|
|
197
|
-
const combinedText = [...testNames, tf.file].join(' ').toLowerCase();
|
|
198
|
-
const matchCount = keywords.filter((kw) => combinedText.includes(kw.toLowerCase())).length;
|
|
199
|
-
if (matchCount >= 2) {
|
|
200
|
-
matches.push({
|
|
201
|
-
file: tf.file,
|
|
202
|
-
/* v8 ignore next 1 */
|
|
203
|
-
testName: testNames[0] ?? tf.file,
|
|
204
|
-
strategy: 'heuristic',
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return matches;
|
|
209
|
-
}
|
|
210
|
-
// ---------------------------------------------------------------------------
|
|
211
|
-
// Keyword extraction
|
|
212
|
-
// ---------------------------------------------------------------------------
|
|
213
|
-
/** Extracts 3–5 meaningful keywords from an AC description text. */
|
|
214
|
-
export function extractKeywords(text) {
|
|
215
|
-
const words = text
|
|
216
|
-
.toLowerCase()
|
|
217
|
-
.replace(/[^a-zA-Z0-9\s_àáéíóúñüÀÁÉÍÓÚÑÜ]/g, ' ')
|
|
218
|
-
.split(/\s+/)
|
|
219
|
-
.filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
|
|
220
|
-
// De-duplicate preserving order
|
|
221
|
-
const seen = new Set();
|
|
222
|
-
const unique = [];
|
|
223
|
-
for (const w of words) {
|
|
224
|
-
if (!seen.has(w)) {
|
|
225
|
-
seen.add(w);
|
|
226
|
-
unique.push(w);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return unique.slice(0, 5);
|
|
230
|
-
}
|
|
231
|
-
// ---------------------------------------------------------------------------
|
|
232
|
-
// Test name extraction helpers
|
|
233
|
-
// ---------------------------------------------------------------------------
|
|
234
|
-
/** Patterns for extracting test block names from source code. */
|
|
235
|
-
const TEST_NAME_PATTERNS = [
|
|
236
|
-
/(?:describe|it|test|context|suite|feature|scenario)\s*\(\s*['"`](.*?)['"`]/g,
|
|
237
|
-
/(?:func\s+Test\w+)\s*\(/g, // Go: func TestXxx(
|
|
238
|
-
/(?:def\s+test_\w+)\s*\(/g, // Python: def test_xxx(
|
|
239
|
-
/#\[test\]\s*(?:fn\s+(\w+))/g, // Rust: #[test] fn name
|
|
240
|
-
/(?:func|fun)\s+(test\w+)\s*\(/gi, // Swift/Kotlin
|
|
241
|
-
];
|
|
242
|
-
/** Extracts the first matching test name from source code. */
|
|
243
|
-
function extractTestName(content, nearPattern) {
|
|
244
|
-
// Find the line with the pattern match, then look for a nearby test name
|
|
245
|
-
const lines = content.split('\n');
|
|
246
|
-
for (let i = 0; i < lines.length; i++) {
|
|
247
|
-
/* v8 ignore next 1 */
|
|
248
|
-
const line = lines[i] ?? '';
|
|
249
|
-
if (!nearPattern.test(line)) {
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
// Look in ±5 lines for a test name
|
|
253
|
-
const start = Math.max(0, i - 5);
|
|
254
|
-
const end = Math.min(lines.length - 1, i + 5);
|
|
255
|
-
for (let j = start; j <= end; j++) {
|
|
256
|
-
/* v8 ignore next 1 */
|
|
257
|
-
const nearby = lines[j] ?? '';
|
|
258
|
-
const nameMatch = /(?:describe|it|test|context)\s*\(\s*['"`](.*?)['"`]/.exec(nearby);
|
|
259
|
-
if (nameMatch?.[1]) {
|
|
260
|
-
return nameMatch[1];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return line.trim().slice(0, 80);
|
|
264
|
-
}
|
|
265
|
-
return '';
|
|
266
|
-
}
|
|
267
|
-
/** Extracts all test/describe block names from source code. */
|
|
268
|
-
function extractAllTestNames(content) {
|
|
269
|
-
const names = [];
|
|
270
|
-
for (const pattern of TEST_NAME_PATTERNS) {
|
|
271
|
-
pattern.lastIndex = 0;
|
|
272
|
-
let match;
|
|
273
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
274
|
-
/* v8 ignore next 1 */
|
|
275
|
-
const name = match[1] ?? match[0];
|
|
276
|
-
/* v8 ignore next 1 */
|
|
277
|
-
if (name) {
|
|
278
|
-
names.push(name);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return names;
|
|
283
|
-
}
|
|
284
|
-
// ---------------------------------------------------------------------------
|
|
285
86
|
// Result builder
|
|
286
87
|
// ---------------------------------------------------------------------------
|
|
287
88
|
function buildResult(acId, description, status, strategy, rawMatches, testFiles) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"criteria-mapper.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kEAAkE;
|
|
1
|
+
{"version":3,"file":"criteria-mapper.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const STOP_WORDS: Set<string>;
|
|
2
|
+
/** Extracts 3-5 meaningful keywords from an AC description text. */
|
|
3
|
+
export declare function extractKeywords(text: string): readonly string[];
|
|
4
|
+
/** Patterns for extracting test block names from source code. */
|
|
5
|
+
export declare const TEST_NAME_PATTERNS: RegExp[];
|
|
6
|
+
/** Extracts the first matching test name from source code. */
|
|
7
|
+
export declare function extractTestName(content: string, nearPattern: RegExp): string;
|
|
8
|
+
/** Extracts all test/describe block names from source code. */
|
|
9
|
+
export declare function extractAllTestNames(content: string): readonly string[];
|
|
10
|
+
//# sourceMappingURL=keyword-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-extractor.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/keyword-extractor.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,aAqErB,CAAC;AAEH,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAkB/D;AAMD,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,UAM9B,CAAC;AAEF,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuB5E;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAetE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// engine/spec-coverage/keyword-extractor.ts — Keyword extraction and test name parsing.
|
|
2
|
+
// Extracted from criteria-mapper.ts to keep file sizes within limits.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Stop words for heuristic keyword extraction
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export const STOP_WORDS = new Set([
|
|
7
|
+
'the',
|
|
8
|
+
'a',
|
|
9
|
+
'an',
|
|
10
|
+
'is',
|
|
11
|
+
'are',
|
|
12
|
+
'was',
|
|
13
|
+
'were',
|
|
14
|
+
'be',
|
|
15
|
+
'been',
|
|
16
|
+
'being',
|
|
17
|
+
'have',
|
|
18
|
+
'has',
|
|
19
|
+
'had',
|
|
20
|
+
'do',
|
|
21
|
+
'does',
|
|
22
|
+
'did',
|
|
23
|
+
'will',
|
|
24
|
+
'would',
|
|
25
|
+
'could',
|
|
26
|
+
'should',
|
|
27
|
+
'may',
|
|
28
|
+
'might',
|
|
29
|
+
'shall',
|
|
30
|
+
'must',
|
|
31
|
+
'can',
|
|
32
|
+
'to',
|
|
33
|
+
'of',
|
|
34
|
+
'in',
|
|
35
|
+
'on',
|
|
36
|
+
'at',
|
|
37
|
+
'by',
|
|
38
|
+
'for',
|
|
39
|
+
'with',
|
|
40
|
+
'from',
|
|
41
|
+
'as',
|
|
42
|
+
'and',
|
|
43
|
+
'or',
|
|
44
|
+
'but',
|
|
45
|
+
'not',
|
|
46
|
+
'no',
|
|
47
|
+
'if',
|
|
48
|
+
'when',
|
|
49
|
+
'where',
|
|
50
|
+
'that',
|
|
51
|
+
'which',
|
|
52
|
+
'this',
|
|
53
|
+
'it',
|
|
54
|
+
'its',
|
|
55
|
+
'el',
|
|
56
|
+
'la',
|
|
57
|
+
'los',
|
|
58
|
+
'las',
|
|
59
|
+
'un',
|
|
60
|
+
'una',
|
|
61
|
+
'de',
|
|
62
|
+
'del',
|
|
63
|
+
'en',
|
|
64
|
+
'que',
|
|
65
|
+
'se',
|
|
66
|
+
'por',
|
|
67
|
+
'para',
|
|
68
|
+
'con',
|
|
69
|
+
'al',
|
|
70
|
+
'lo',
|
|
71
|
+
'le',
|
|
72
|
+
'les',
|
|
73
|
+
'y',
|
|
74
|
+
'o',
|
|
75
|
+
]);
|
|
76
|
+
/** Extracts 3-5 meaningful keywords from an AC description text. */
|
|
77
|
+
export function extractKeywords(text) {
|
|
78
|
+
const words = text
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/[^a-zA-Z0-9\s_àáéíóúñüÀÁÉÍÓÚÑÜ]/g, ' ')
|
|
81
|
+
.split(/\s+/)
|
|
82
|
+
.filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
|
|
83
|
+
// De-duplicate preserving order
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
const unique = [];
|
|
86
|
+
for (const w of words) {
|
|
87
|
+
if (!seen.has(w)) {
|
|
88
|
+
seen.add(w);
|
|
89
|
+
unique.push(w);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return unique.slice(0, 5);
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Test name extraction helpers
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/** Patterns for extracting test block names from source code. */
|
|
98
|
+
export const TEST_NAME_PATTERNS = [
|
|
99
|
+
/(?:describe|it|test|context|suite|feature|scenario)\s*\(\s*['"`](.*?)['"`]/g,
|
|
100
|
+
/(?:func\s+Test\w+)\s*\(/g, // Go: func TestXxx(
|
|
101
|
+
/(?:def\s+test_\w+)\s*\(/g, // Python: def test_xxx(
|
|
102
|
+
/#\[test\]\s*(?:fn\s+(\w+))/g, // Rust: #[test] fn name
|
|
103
|
+
/(?:func|fun)\s+(test\w+)\s*\(/gi, // Swift/Kotlin
|
|
104
|
+
];
|
|
105
|
+
/** Extracts the first matching test name from source code. */
|
|
106
|
+
export function extractTestName(content, nearPattern) {
|
|
107
|
+
// Find the line with the pattern match, then look for a nearby test name
|
|
108
|
+
const lines = content.split('\n');
|
|
109
|
+
for (let i = 0; i < lines.length; i++) {
|
|
110
|
+
/* v8 ignore next 1 */
|
|
111
|
+
const line = lines[i] ?? '';
|
|
112
|
+
if (!nearPattern.test(line)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Look in ±5 lines for a test name
|
|
116
|
+
const start = Math.max(0, i - 5);
|
|
117
|
+
const end = Math.min(lines.length - 1, i + 5);
|
|
118
|
+
for (let j = start; j <= end; j++) {
|
|
119
|
+
/* v8 ignore next 1 */
|
|
120
|
+
const nearby = lines[j] ?? '';
|
|
121
|
+
const nameMatch = /(?:describe|it|test|context)\s*\(\s*['"`](.*?)['"`]/.exec(nearby);
|
|
122
|
+
if (nameMatch?.[1]) {
|
|
123
|
+
return nameMatch[1];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return line.trim().slice(0, 80);
|
|
127
|
+
}
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
/** Extracts all test/describe block names from source code. */
|
|
131
|
+
export function extractAllTestNames(content) {
|
|
132
|
+
const names = [];
|
|
133
|
+
for (const pattern of TEST_NAME_PATTERNS) {
|
|
134
|
+
pattern.lastIndex = 0;
|
|
135
|
+
let match;
|
|
136
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
137
|
+
/* v8 ignore next 1 */
|
|
138
|
+
const name = match[1] ?? match[0];
|
|
139
|
+
/* v8 ignore next 1 */
|
|
140
|
+
if (name) {
|
|
141
|
+
names.push(name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return names;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=keyword-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-extractor.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/keyword-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TestMatch, CoverageTestFile } from '../../types/index.js';
|
|
2
|
+
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
3
|
+
export declare function findDirectReferences(acId: string, testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
4
|
+
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
5
|
+
export declare function findSpecReferences(specId: string, testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
6
|
+
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
7
|
+
export declare function findKeywordMatches(keywords: readonly string[], testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
8
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
9
|
+
//# sourceMappingURL=test-matchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-matchers.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/test-matchers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxE,mFAAmF;AACnF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAkBb;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAgBb;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAqBb;AAGD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// engine/spec-coverage/test-matchers.ts — Test-to-criterion matching strategies.
|
|
2
|
+
// Extracted from criteria-mapper.ts to keep file sizes within limits.
|
|
3
|
+
import { extractTestName, extractAllTestNames } from './keyword-extractor.js';
|
|
4
|
+
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
5
|
+
export function findDirectReferences(acId, testFiles, testContents) {
|
|
6
|
+
const matches = [];
|
|
7
|
+
// Build regex variants: AC-01, AC01, #AC-01, AC 01
|
|
8
|
+
const acNum = acId.replace('AC-', '');
|
|
9
|
+
const pattern = new RegExp(`\\b(?:AC[-\\s]?${acNum}|#AC-?${acNum})\\b`, 'i');
|
|
10
|
+
for (const tf of testFiles) {
|
|
11
|
+
const content = testContents.get(tf.file) ?? '';
|
|
12
|
+
if (!pattern.test(content)) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
// Extract the test name from the first matching line
|
|
16
|
+
const testName = extractTestName(content, pattern);
|
|
17
|
+
matches.push({ file: tf.file, testName, strategy: 'direct-reference' });
|
|
18
|
+
}
|
|
19
|
+
return matches;
|
|
20
|
+
}
|
|
21
|
+
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
22
|
+
export function findSpecReferences(specId, testFiles, testContents) {
|
|
23
|
+
const matches = [];
|
|
24
|
+
const specPattern = new RegExp(`\\b${specId.replace('-', '[-_]?')}\\b`, 'i');
|
|
25
|
+
for (const tf of testFiles) {
|
|
26
|
+
const inPath = specPattern.test(tf.file);
|
|
27
|
+
const content = testContents.get(tf.file) ?? '';
|
|
28
|
+
const inContent = specPattern.test(content);
|
|
29
|
+
if (!inPath && !inContent) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const testName = inContent ? extractTestName(content, specPattern) : tf.file;
|
|
33
|
+
matches.push({ file: tf.file, testName, strategy: 'spec-reference' });
|
|
34
|
+
}
|
|
35
|
+
return matches;
|
|
36
|
+
}
|
|
37
|
+
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
38
|
+
export function findKeywordMatches(keywords, testFiles, testContents) {
|
|
39
|
+
const matches = [];
|
|
40
|
+
for (const tf of testFiles) {
|
|
41
|
+
const content = testContents.get(tf.file) ?? '';
|
|
42
|
+
// Extract all describe/it/test block names
|
|
43
|
+
const testNames = extractAllTestNames(content);
|
|
44
|
+
const combinedText = [...testNames, tf.file].join(' ').toLowerCase();
|
|
45
|
+
const matchCount = keywords.filter((kw) => combinedText.includes(kw.toLowerCase())).length;
|
|
46
|
+
if (matchCount >= 2) {
|
|
47
|
+
matches.push({
|
|
48
|
+
file: tf.file,
|
|
49
|
+
/* v8 ignore next 1 */
|
|
50
|
+
testName: testNames[0] ?? tf.file,
|
|
51
|
+
strategy: 'heuristic',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return matches;
|
|
56
|
+
}
|
|
57
|
+
// Re-export extractKeywords for backward compatibility
|
|
58
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
59
|
+
//# sourceMappingURL=test-matchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-matchers.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/test-matchers.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,sEAAsE;AAGtE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE9E,mFAAmF;AACnF,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,SAAsC,EACtC,YAAyC;IAEzC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,mDAAmD;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,kBAAkB,KAAK,SAAS,KAAK,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7E,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,qDAAqD;QACrD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,SAAsC,EACtC,YAAyC;IAEzC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAE7E,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,kBAAkB,CAChC,QAA2B,EAC3B,SAAsC,EACtC,YAAyC;IAEzC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,2CAA2C;QAC3C,MAAM,SAAS,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,CAAC,GAAG,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAErE,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3F,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,sBAAsB;gBACtB,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI;gBACjC,QAAQ,EAAE,WAAW;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uDAAuD;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { SpecTemplateEntry } from '../../types/spec-templates.js';
|
|
2
|
-
/** Extra built-in spec templates (data, security, performance). */
|
|
2
|
+
/** Extra built-in spec templates (data, security, performance, integration). */
|
|
3
3
|
export declare const EXTRA_TEMPLATES: SpecTemplateEntry[];
|
|
4
4
|
//# sourceMappingURL=catalog-extra.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-extra.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-templates/catalog-extra.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-extra.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-templates/catalog-extra.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAOvE,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,iBAAiB,EAK9C,CAAC"}
|