@memberjunction/query-gen 3.4.0 → 4.1.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/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +54 -0
- package/README.md +30 -2
- package/dist/cli/commands/export.js +35 -65
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +114 -115
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/validate.js +40 -70
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/config.d.ts +1 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +8 -7
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/index.js +11 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/core/EntityGrouper.d.ts +5 -2
- package/dist/core/EntityGrouper.d.ts.map +1 -1
- package/dist/core/EntityGrouper.js +94 -39
- package/dist/core/EntityGrouper.js.map +1 -1
- package/dist/core/MetadataExporter.d.ts +2 -2
- package/dist/core/MetadataExporter.js +9 -36
- package/dist/core/MetadataExporter.js.map +1 -1
- package/dist/core/QueryDatabaseWriter.d.ts +1 -1
- package/dist/core/QueryDatabaseWriter.js +8 -12
- package/dist/core/QueryDatabaseWriter.js.map +1 -1
- package/dist/core/QueryFixer.d.ts +2 -2
- package/dist/core/QueryFixer.js +11 -17
- package/dist/core/QueryFixer.js.map +1 -1
- package/dist/core/QueryRefiner.d.ts +3 -3
- package/dist/core/QueryRefiner.js +22 -29
- package/dist/core/QueryRefiner.js.map +1 -1
- package/dist/core/QueryTester.d.ts +2 -2
- package/dist/core/QueryTester.js +11 -44
- package/dist/core/QueryTester.js.map +1 -1
- package/dist/core/QueryWriter.d.ts +2 -2
- package/dist/core/QueryWriter.js +12 -18
- package/dist/core/QueryWriter.js.map +1 -1
- package/dist/core/QuestionGenerator.d.ts +2 -2
- package/dist/core/QuestionGenerator.js +16 -22
- package/dist/core/QuestionGenerator.js.map +1 -1
- package/dist/data/schema.js +1 -2
- package/dist/data/schema.js.map +1 -1
- package/dist/index.d.ts +18 -18
- package/dist/index.js +18 -59
- package/dist/index.js.map +1 -1
- package/dist/prompts/PromptNames.js +5 -8
- package/dist/prompts/PromptNames.js.map +1 -1
- package/dist/utils/category-builder.d.ts +2 -2
- package/dist/utils/category-builder.js +2 -7
- package/dist/utils/category-builder.js.map +1 -1
- package/dist/utils/entity-helpers.d.ts +1 -1
- package/dist/utils/entity-helpers.js +7 -17
- package/dist/utils/entity-helpers.js.map +1 -1
- package/dist/utils/error-handlers.js +3 -9
- package/dist/utils/error-handlers.js.map +1 -1
- package/dist/utils/graph-helpers.js +3 -9
- package/dist/utils/graph-helpers.js.map +1 -1
- package/dist/utils/prompt-helpers.d.ts +1 -1
- package/dist/utils/prompt-helpers.js +8 -12
- package/dist/utils/prompt-helpers.js.map +1 -1
- package/dist/utils/user-helpers.js +3 -7
- package/dist/utils/user-helpers.js.map +1 -1
- package/dist/vectors/EmbeddingService.d.ts +1 -1
- package/dist/vectors/EmbeddingService.js +3 -8
- package/dist/vectors/EmbeddingService.js.map +1 -1
- package/dist/vectors/SimilaritySearch.d.ts +1 -1
- package/dist/vectors/SimilaritySearch.js +19 -20
- package/dist/vectors/SimilaritySearch.js.map +1 -1
- package/package.json +24 -17
- package/src/__tests__/golden-queries-loader.test.js +181 -0
- package/src/cli/commands/generate.ts +52 -21
- package/src/cli/config.ts +10 -2
- package/src/cli/index.ts +4 -1
- package/src/core/EntityGrouper.ts +75 -11
- package/src/core/QueryTester.ts +1 -1
- package/tsconfig.json +5 -35
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Graph visualization and entity metadata formatting utilities
|
|
4
3
|
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatEntitiesForPrompt = exports.generateMermaidDiagram = exports.generateRelationshipGraph = void 0;
|
|
7
4
|
/**
|
|
8
5
|
* Generates a simple text-based relationship graph for LLM prompts
|
|
9
6
|
*
|
|
@@ -14,7 +11,7 @@ exports.formatEntitiesForPrompt = exports.generateMermaidDiagram = exports.gener
|
|
|
14
11
|
* Products: → OrderDetails, → Categories
|
|
15
12
|
* ```
|
|
16
13
|
*/
|
|
17
|
-
function generateRelationshipGraph(entities) {
|
|
14
|
+
export function generateRelationshipGraph(entities) {
|
|
18
15
|
const lines = [];
|
|
19
16
|
for (const entity of entities) {
|
|
20
17
|
if (entity.RelatedEntities.length === 0) {
|
|
@@ -28,7 +25,6 @@ function generateRelationshipGraph(entities) {
|
|
|
28
25
|
}
|
|
29
26
|
return lines.join('\n');
|
|
30
27
|
}
|
|
31
|
-
exports.generateRelationshipGraph = generateRelationshipGraph;
|
|
32
28
|
/**
|
|
33
29
|
* Generates a Mermaid diagram for richer visualization
|
|
34
30
|
*
|
|
@@ -40,7 +36,7 @@ exports.generateRelationshipGraph = generateRelationshipGraph;
|
|
|
40
36
|
* Orders[Orders] --> OrderDetails[OrderDetails]
|
|
41
37
|
* ```
|
|
42
38
|
*/
|
|
43
|
-
function generateMermaidDiagram(entities) {
|
|
39
|
+
export function generateMermaidDiagram(entities) {
|
|
44
40
|
const lines = ['graph LR'];
|
|
45
41
|
const processedPairs = new Set();
|
|
46
42
|
for (const entity of entities) {
|
|
@@ -56,7 +52,6 @@ function generateMermaidDiagram(entities) {
|
|
|
56
52
|
}
|
|
57
53
|
return lines.join('\n');
|
|
58
54
|
}
|
|
59
|
-
exports.generateMermaidDiagram = generateMermaidDiagram;
|
|
60
55
|
/**
|
|
61
56
|
* Formats entity metadata for LLM prompt (concise version with key info)
|
|
62
57
|
*
|
|
@@ -66,7 +61,7 @@ exports.generateMermaidDiagram = generateMermaidDiagram;
|
|
|
66
61
|
* - Field count (as a proxy for data richness)
|
|
67
62
|
* - Related entities with relationship types
|
|
68
63
|
*/
|
|
69
|
-
function formatEntitiesForPrompt(entities) {
|
|
64
|
+
export function formatEntitiesForPrompt(entities) {
|
|
70
65
|
return entities.map(entity => ({
|
|
71
66
|
Name: entity.Name,
|
|
72
67
|
Description: entity.Description || 'No description available',
|
|
@@ -78,5 +73,4 @@ function formatEntitiesForPrompt(entities) {
|
|
|
78
73
|
}))
|
|
79
74
|
}));
|
|
80
75
|
}
|
|
81
|
-
exports.formatEntitiesForPrompt = formatEntitiesForPrompt;
|
|
82
76
|
//# sourceMappingURL=graph-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-helpers.js","sourceRoot":"","sources":["../../src/utils/graph-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph-helpers.js","sourceRoot":"","sources":["../../src/utils/graph-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAsB;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,sBAAsB,CAAC,CAAC;YACjD,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe;aACrC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,aAAa,EAAE,CAAC;aACpC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAsB;IAC3D,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3B,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEvD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YACzC,MAAM,eAAe,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEnE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,KAAK,cAAc,IAAI,MAAM,CAAC,IAAI,SAAS,eAAe,IAAI,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC;gBAC/F,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAsB;IAC5D,OAAO,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,0BAA0B;QAC7D,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,KAAK;QACtC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;QAChC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,EAAE,GAAG,CAAC,aAAa;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { UserInfo } from '@memberjunction/core';
|
|
5
5
|
import { AIPromptEntityExtended } from '@memberjunction/ai-core-plus';
|
|
6
|
-
import { QueryGenConfig } from '../cli/config';
|
|
6
|
+
import { QueryGenConfig } from '../cli/config.js';
|
|
7
7
|
/**
|
|
8
8
|
* Execute a prompt with optional model/vendor overrides from QueryGenConfig
|
|
9
9
|
*
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Prompt execution helpers with model/vendor override support
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const ai_prompts_1 = require("@memberjunction/ai-prompts");
|
|
9
|
-
const aiengine_1 = require("@memberjunction/aiengine");
|
|
4
|
+
import { AIPromptParams } from '@memberjunction/ai-core-plus';
|
|
5
|
+
import { AIPromptRunner } from '@memberjunction/ai-prompts';
|
|
6
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
10
7
|
/**
|
|
11
8
|
* Execute a prompt with optional model/vendor overrides from QueryGenConfig
|
|
12
9
|
*
|
|
@@ -20,8 +17,8 @@ const aiengine_1 = require("@memberjunction/aiengine");
|
|
|
20
17
|
* @param config - QueryGen configuration (for model/vendor overrides)
|
|
21
18
|
* @returns Promise resolving to the prompt result
|
|
22
19
|
*/
|
|
23
|
-
async function executePromptWithOverrides(prompt, data, contextUser, config) {
|
|
24
|
-
const promptParams = new
|
|
20
|
+
export async function executePromptWithOverrides(prompt, data, contextUser, config) {
|
|
21
|
+
const promptParams = new AIPromptParams();
|
|
25
22
|
promptParams.prompt = prompt;
|
|
26
23
|
promptParams.data = data;
|
|
27
24
|
promptParams.contextUser = contextUser;
|
|
@@ -33,10 +30,9 @@ async function executePromptWithOverrides(prompt, data, contextUser, config) {
|
|
|
33
30
|
promptParams.override = overrideIds;
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
|
-
const runner = new
|
|
33
|
+
const runner = new AIPromptRunner();
|
|
37
34
|
return await runner.ExecutePrompt(promptParams);
|
|
38
35
|
}
|
|
39
|
-
exports.executePromptWithOverrides = executePromptWithOverrides;
|
|
40
36
|
/**
|
|
41
37
|
* Resolve model/vendor names to IDs for AIPromptParams.override
|
|
42
38
|
*
|
|
@@ -49,14 +45,14 @@ function resolveModelVendorOverrides(config) {
|
|
|
49
45
|
const result = {};
|
|
50
46
|
// Look up model ID from AIEngine cache if modelOverride is set
|
|
51
47
|
if (config.modelOverride) {
|
|
52
|
-
const model =
|
|
48
|
+
const model = AIEngine.Instance.Models.find(m => m.Name === config.modelOverride);
|
|
53
49
|
if (model && model.ID) {
|
|
54
50
|
result.modelId = model.ID;
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
53
|
// Look up vendor ID from AIEngine cache if vendorOverride is set
|
|
58
54
|
if (config.vendorOverride) {
|
|
59
|
-
const vendor =
|
|
55
|
+
const vendor = AIEngine.Instance.Vendors.find(v => v.Name === config.vendorOverride);
|
|
60
56
|
if (vendor && vendor.ID) {
|
|
61
57
|
result.vendorId = vendor.ID;
|
|
62
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-helpers.js","sourceRoot":"","sources":["../../src/utils/prompt-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompt-helpers.js","sourceRoot":"","sources":["../../src/utils/prompt-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,MAA8B,EAC9B,IAA6B,EAC7B,WAAqB,EACrB,MAAsB;IAEtB,MAAM,YAAY,GAAG,IAAI,cAAc,EAAE,CAAC;IAC1C,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;IAC7B,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,WAAW,GAAG,WAAW,CAAC;IACvC,YAAY,CAAC,cAAc,GAAG,KAAK,CAAC;IAEpC,sEAAsE;IACtE,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAClD,MAAM,WAAW,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YAChD,YAAY,CAAC,QAAQ,GAAG,WAAW,CAAC;QACtC,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IACpC,OAAO,MAAM,MAAM,CAAC,aAAa,CAAI,YAAY,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,2BAA2B,CAClC,MAAsB;IAEtB,MAAM,MAAM,GAA4C,EAAE,CAAC;IAE3D,+DAA+D;IAC/D,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC;QAClF,IAAI,KAAK,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACtB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,iEAAiE;IACjE,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC;QACrF,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* User helper utilities for QueryGen CLI operations
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
exports.getSystemUser = void 0;
|
|
7
|
-
const sqlserver_dataprovider_1 = require("@memberjunction/sqlserver-dataprovider");
|
|
4
|
+
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
8
5
|
/**
|
|
9
6
|
* Get the system user from UserCache
|
|
10
7
|
*
|
|
@@ -14,8 +11,8 @@ const sqlserver_dataprovider_1 = require("@memberjunction/sqlserver-dataprovider
|
|
|
14
11
|
* @returns The System UserInfo object from the cache
|
|
15
12
|
* @throws Error if System user is not found in cache or doesn't have Developer role
|
|
16
13
|
*/
|
|
17
|
-
function getSystemUser() {
|
|
18
|
-
const sysUser =
|
|
14
|
+
export function getSystemUser() {
|
|
15
|
+
const sysUser = UserCache.Instance.UserByName("System", false);
|
|
19
16
|
if (!sysUser) {
|
|
20
17
|
throw new Error("System user not found in cache. Ensure the database provider is initialized " +
|
|
21
18
|
"before running QueryGen commands (e.g., via 'mj querygen' which initializes the provider).");
|
|
@@ -28,5 +25,4 @@ function getSystemUser() {
|
|
|
28
25
|
}
|
|
29
26
|
return sysUser;
|
|
30
27
|
}
|
|
31
|
-
exports.getSystemUser = getSystemUser;
|
|
32
28
|
//# sourceMappingURL=user-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-helpers.js","sourceRoot":"","sources":["../../src/utils/user-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"user-helpers.js","sourceRoot":"","sources":["../../src/utils/user-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,8EAA8E;YAC9E,4FAA4F,CAC7F,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAClE,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,WAAW,CAC/D,CAAC;IAEF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,kDAAkD;YAClD,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Wraps AIEngine embedding functionality for QueryGen use cases.
|
|
5
5
|
* Generates embeddings for multiple fields (name, userQuestion, description, technicalDescription).
|
|
6
6
|
*/
|
|
7
|
-
import { QueryEmbeddings, GoldenQuery, EmbeddedGoldenQuery } from '../data/schema';
|
|
7
|
+
import { QueryEmbeddings, GoldenQuery, EmbeddedGoldenQuery } from '../data/schema.js';
|
|
8
8
|
/**
|
|
9
9
|
* Service for generating embeddings using AI Engine
|
|
10
10
|
*/
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* EmbeddingService - Generates embeddings for queries and golden queries
|
|
4
3
|
*
|
|
5
4
|
* Wraps AIEngine embedding functionality for QueryGen use cases.
|
|
6
5
|
* Generates embeddings for multiple fields (name, userQuestion, description, technicalDescription).
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
exports.EmbeddingService = void 0;
|
|
10
|
-
const aiengine_1 = require("@memberjunction/aiengine");
|
|
7
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
11
8
|
/**
|
|
12
9
|
* Service for generating embeddings using AI Engine
|
|
13
10
|
*/
|
|
14
|
-
class EmbeddingService {
|
|
15
|
-
modelName;
|
|
11
|
+
export class EmbeddingService {
|
|
16
12
|
/**
|
|
17
13
|
* Create an EmbeddingService with the specified embedding model
|
|
18
14
|
*
|
|
@@ -33,7 +29,7 @@ class EmbeddingService {
|
|
|
33
29
|
* @returns Embeddings for all fields
|
|
34
30
|
*/
|
|
35
31
|
async embedQuery(query) {
|
|
36
|
-
const aiEngine =
|
|
32
|
+
const aiEngine = AIEngine.Instance;
|
|
37
33
|
// Generate embeddings for each field in parallel
|
|
38
34
|
const [userQuestionResult, descResult, techDescResult] = await Promise.all([
|
|
39
35
|
aiEngine.EmbedTextLocal(query.userQuestion),
|
|
@@ -86,5 +82,4 @@ class EmbeddingService {
|
|
|
86
82
|
return embeddings;
|
|
87
83
|
}
|
|
88
84
|
}
|
|
89
|
-
exports.EmbeddingService = EmbeddingService;
|
|
90
85
|
//# sourceMappingURL=EmbeddingService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddingService.js","sourceRoot":"","sources":["../../src/vectors/EmbeddingService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EmbeddingService.js","sourceRoot":"","sources":["../../src/vectors/EmbeddingService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAG3B;;;;OAIG;IACH,YAAY,YAAoB,wBAAwB;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAU,CAAC,KAIhB;QACC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAEnC,iDAAiD;QACjD,MAAM,CAAC,kBAAkB,EAAE,UAAU,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACzE,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC;YAC3C,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC;YAC1C,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,oBAAoB,CAAC;SACpD,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;YACrD,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;YAC5C,oBAAoB,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;SAC1D,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,kBAAkB,CAAC,aAA4B;QACnD,MAAM,QAAQ,GAA0B,EAAE,CAAC;QAE3C,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;gBACvC,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;aACjD,CAAC,CAAC;YAEH,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK;gBACL,UAAU;aACX,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CAChB,OAIE;QAEF,MAAM,UAAU,GAAsB,EAAE,CAAC;QAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements weighted similarity search across multiple fields (name, userQuestion,
|
|
5
5
|
* description, technicalDescription) to find the most relevant few-shot examples.
|
|
6
6
|
*/
|
|
7
|
-
import { QueryEmbeddings, EmbeddedGoldenQuery, SimilarQuery } from '../data/schema';
|
|
7
|
+
import { QueryEmbeddings, EmbeddedGoldenQuery, SimilarQuery } from '../data/schema.js';
|
|
8
8
|
import { SimpleVectorService } from '@memberjunction/ai-vectors-memory';
|
|
9
9
|
/**
|
|
10
10
|
* SimilaritySearch class
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* SimilaritySearch - Finds similar golden queries using weighted cosine similarity
|
|
4
3
|
*
|
|
5
4
|
* Implements weighted similarity search across multiple fields (name, userQuestion,
|
|
6
5
|
* description, technicalDescription) to find the most relevant few-shot examples.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
exports.SimilaritySearch = void 0;
|
|
10
|
-
const ai_vectors_memory_1 = require("@memberjunction/ai-vectors-memory");
|
|
7
|
+
import { SimpleVectorService } from '@memberjunction/ai-vectors-memory';
|
|
11
8
|
/**
|
|
12
9
|
* SimilaritySearch class
|
|
13
10
|
* Finds most similar golden queries using weighted cosine similarity across multiple fields
|
|
14
11
|
*/
|
|
15
|
-
class SimilaritySearch extends
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
export class SimilaritySearch extends SimpleVectorService {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
/**
|
|
16
|
+
* Weights for each field in similarity calculation
|
|
17
|
+
* Total weights sum to 1.0
|
|
18
|
+
*
|
|
19
|
+
* Weight distribution prioritizes technical specifications:
|
|
20
|
+
* - userQuestion: 0.20 (less important - natural language is variable)
|
|
21
|
+
* - description: 0.40 (high-level business logic matching)
|
|
22
|
+
* - technicalDescription: 0.40 (technical implementation details)
|
|
23
|
+
*/
|
|
24
|
+
this.weights = {
|
|
25
|
+
userQuestion: 0.20,
|
|
26
|
+
description: 0.40,
|
|
27
|
+
technicalDescription: 0.40
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
30
|
/**
|
|
31
31
|
* Find similar golden queries using weighted cosine similarity
|
|
32
32
|
*
|
|
@@ -81,5 +81,4 @@ class SimilaritySearch extends ai_vectors_memory_1.SimpleVectorService {
|
|
|
81
81
|
.slice(0, topK);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
exports.SimilaritySearch = SimilaritySearch;
|
|
85
84
|
//# sourceMappingURL=SimilaritySearch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimilaritySearch.js","sourceRoot":"","sources":["../../src/vectors/SimilaritySearch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SimilaritySearch.js","sourceRoot":"","sources":["../../src/vectors/SimilaritySearch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAYxE;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,mBAAmB;IAAzD;;QACE;;;;;;;;WAQG;QACc,YAAO,GAAiB;YACvC,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;YACjB,oBAAoB,EAAE,IAAI;SAC3B,CAAC;IAqEJ,CAAC;IAnEC;;;;;;;;;;OAUG;IACH,KAAK,CAAC,kBAAkB,CACtB,eAAgC,EAChC,gBAAuC,EACvC,OAAe,CAAC;QAEhB,sDAAsD;QACtD,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YACjD,MAAM,WAAW,GAAG,IAAI,CAAC,0BAA0B,CAAC,eAAe,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YACxF,MAAM,aAAa,GAAG,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;YAE/D,OAAO;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,UAAU,EAAE,aAAa;gBACzB,WAAW;aACZ,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,sDAAsD;QACtD,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACK,0BAA0B,CAChC,eAAgC,EAChC,gBAAiC;QAEjC,OAAO;YACL,eAAe,EAAE,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,YAAY,EAAE,gBAAgB,CAAC,YAAY,CAAC;YACnG,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC;YACzF,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;SAChH,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAAC,WAAwC;QACrE,OAAO,CACL,WAAW,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY;YACvD,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW;YAC9C,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAC5D,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,YAA4B,EAAE,IAAY;QAC3D,OAAO,YAAY;aAChB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;aAC3C,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACpB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/query-gen",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "4.1.0",
|
|
4
5
|
"description": "AI-powered generation of domain-specific SQL query templates with automatic testing, refinement, and metadata export",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
@@ -8,11 +9,14 @@
|
|
|
8
9
|
"mj-querygen": "./dist/cli/index.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
+
"build": "tsc && tsc-alias -f",
|
|
12
13
|
"watch": "tsc --watch",
|
|
13
14
|
"clean": "rimraf dist",
|
|
14
15
|
"lint": "eslint src --ext .ts",
|
|
15
|
-
"format": "prettier --write \"src/**/*.ts\""
|
|
16
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
17
|
+
"test": "node --test src/__tests__/*.test.js",
|
|
18
|
+
"test:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
19
|
+
"test:watch": "node --test --watch src/__tests__/*.test.js"
|
|
16
20
|
},
|
|
17
21
|
"keywords": [
|
|
18
22
|
"memberjunction",
|
|
@@ -25,25 +29,28 @@
|
|
|
25
29
|
"author": "MemberJunction",
|
|
26
30
|
"license": "MIT",
|
|
27
31
|
"dependencies": {
|
|
28
|
-
"@memberjunction/ai": "
|
|
29
|
-
"@memberjunction/ai-core-plus": "
|
|
30
|
-
"@memberjunction/aiengine": "
|
|
31
|
-
"@memberjunction/ai-prompts": "
|
|
32
|
-
"@memberjunction/ai-vectors-memory": "
|
|
33
|
-
"@memberjunction/core": "
|
|
34
|
-
"@memberjunction/core-entities": "
|
|
35
|
-
"@memberjunction/global": "
|
|
36
|
-
"@memberjunction/sqlserver-dataprovider": "
|
|
37
|
-
"chalk": "^
|
|
38
|
-
"commander": "^
|
|
32
|
+
"@memberjunction/ai": "4.1.0",
|
|
33
|
+
"@memberjunction/ai-core-plus": "4.1.0",
|
|
34
|
+
"@memberjunction/aiengine": "4.1.0",
|
|
35
|
+
"@memberjunction/ai-prompts": "4.1.0",
|
|
36
|
+
"@memberjunction/ai-vectors-memory": "4.1.0",
|
|
37
|
+
"@memberjunction/core": "4.1.0",
|
|
38
|
+
"@memberjunction/core-entities": "4.1.0",
|
|
39
|
+
"@memberjunction/global": "4.1.0",
|
|
40
|
+
"@memberjunction/sqlserver-dataprovider": "4.1.0",
|
|
41
|
+
"chalk": "^5.6.2",
|
|
42
|
+
"commander": "^14.0.3",
|
|
39
43
|
"nunjucks": "^3.2.4",
|
|
40
|
-
"ora": "^
|
|
44
|
+
"ora": "^9.3.0"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
|
-
"@types/
|
|
47
|
+
"@types/jest": "^29.5.12",
|
|
48
|
+
"@types/node": "24.10.11",
|
|
44
49
|
"@types/nunjucks": "^3.2.6",
|
|
50
|
+
"jest": "^29.7.0",
|
|
51
|
+
"ts-jest": "^29.1.2",
|
|
45
52
|
"ts-node-dev": "^2.0.0",
|
|
46
|
-
"typescript": "^5.
|
|
53
|
+
"typescript": "^5.9.3"
|
|
47
54
|
},
|
|
48
55
|
"repository": {
|
|
49
56
|
"type": "git",
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for golden queries loading functionality
|
|
3
|
+
*
|
|
4
|
+
* Tests that the golden-queries.json file can be loaded correctly using
|
|
5
|
+
* the ES module compatible file system approach introduced to fix the
|
|
6
|
+
* JSON import attribute error.
|
|
7
|
+
*
|
|
8
|
+
* Run with: node --test src/__tests__/golden-queries-loader.test.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { test, describe } from 'node:test';
|
|
12
|
+
import assert from 'node:assert';
|
|
13
|
+
import { readFileSync, existsSync } from 'fs';
|
|
14
|
+
import { dirname, join } from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
|
|
17
|
+
// Get the path to the golden-queries.json file relative to this test file
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
|
|
21
|
+
// The test file is at: src/__tests__/golden-queries-loader.test.js
|
|
22
|
+
// The JSON file is at: src/data/golden-queries.json
|
|
23
|
+
// So the relative path is: ../data/golden-queries.json
|
|
24
|
+
const goldenQueriesPathFromSource = join(__dirname, '../data/golden-queries.json');
|
|
25
|
+
|
|
26
|
+
describe('Golden Queries Loader', () => {
|
|
27
|
+
describe('File System Loading', () => {
|
|
28
|
+
test('should find the golden-queries.json file', () => {
|
|
29
|
+
assert.strictEqual(existsSync(goldenQueriesPathFromSource), true,
|
|
30
|
+
`Expected golden-queries.json to exist at ${goldenQueriesPathFromSource}`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should load the golden-queries.json file as valid JSON', () => {
|
|
34
|
+
const content = readFileSync(goldenQueriesPathFromSource, 'utf-8');
|
|
35
|
+
const data = JSON.parse(content);
|
|
36
|
+
|
|
37
|
+
assert.ok(data !== undefined, 'Expected data to be defined');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should contain an array of golden queries', () => {
|
|
41
|
+
const content = readFileSync(goldenQueriesPathFromSource, 'utf-8');
|
|
42
|
+
const data = JSON.parse(content);
|
|
43
|
+
|
|
44
|
+
assert.strictEqual(Array.isArray(data), true, 'Expected data to be an array');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should have at least one golden query', () => {
|
|
48
|
+
const content = readFileSync(goldenQueriesPathFromSource, 'utf-8');
|
|
49
|
+
const data = JSON.parse(content);
|
|
50
|
+
|
|
51
|
+
assert.ok(data.length > 0, 'Expected at least one golden query');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('Golden Query Schema Validation', () => {
|
|
56
|
+
const content = readFileSync(goldenQueriesPathFromSource, 'utf-8');
|
|
57
|
+
const goldenQueries = JSON.parse(content);
|
|
58
|
+
|
|
59
|
+
test('each golden query should have a name', () => {
|
|
60
|
+
for (const query of goldenQueries) {
|
|
61
|
+
assert.ok(query.name !== undefined, 'Expected name to be defined');
|
|
62
|
+
assert.strictEqual(typeof query.name, 'string', 'Expected name to be a string');
|
|
63
|
+
assert.ok(query.name.length > 0, 'Expected name to be non-empty');
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('each golden query should have a userQuestion', () => {
|
|
68
|
+
for (const query of goldenQueries) {
|
|
69
|
+
assert.ok(query.userQuestion !== undefined, 'Expected userQuestion to be defined');
|
|
70
|
+
assert.strictEqual(typeof query.userQuestion, 'string', 'Expected userQuestion to be a string');
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('each golden query should have a description', () => {
|
|
75
|
+
for (const query of goldenQueries) {
|
|
76
|
+
assert.ok(query.description !== undefined, 'Expected description to be defined');
|
|
77
|
+
assert.strictEqual(typeof query.description, 'string', 'Expected description to be a string');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('each golden query should have sql', () => {
|
|
82
|
+
for (const query of goldenQueries) {
|
|
83
|
+
assert.ok(query.sql !== undefined, 'Expected sql to be defined');
|
|
84
|
+
assert.strictEqual(typeof query.sql, 'string', 'Expected sql to be a string');
|
|
85
|
+
assert.ok(query.sql.length > 0, 'Expected sql to be non-empty');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('each golden query should have a parameters array', () => {
|
|
90
|
+
for (const query of goldenQueries) {
|
|
91
|
+
assert.ok(query.parameters !== undefined, 'Expected parameters to be defined');
|
|
92
|
+
assert.strictEqual(Array.isArray(query.parameters), true, 'Expected parameters to be an array');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('each golden query should have a selectClause array', () => {
|
|
97
|
+
for (const query of goldenQueries) {
|
|
98
|
+
assert.ok(query.selectClause !== undefined, 'Expected selectClause to be defined');
|
|
99
|
+
assert.strictEqual(Array.isArray(query.selectClause), true, 'Expected selectClause to be an array');
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('loadGoldenQueries Function Simulation', () => {
|
|
105
|
+
/**
|
|
106
|
+
* Simulates the loadGoldenQueries function from generate.ts
|
|
107
|
+
* to verify the implementation works correctly
|
|
108
|
+
*/
|
|
109
|
+
async function loadGoldenQueries(config) {
|
|
110
|
+
try {
|
|
111
|
+
// This mirrors the implementation in generate.ts
|
|
112
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
113
|
+
const __dirname = dirname(__filename);
|
|
114
|
+
// Adjust path for test location vs generate.ts location
|
|
115
|
+
const goldenQueriesPath = join(__dirname, '../data/golden-queries.json');
|
|
116
|
+
const goldenQueriesData = JSON.parse(readFileSync(goldenQueriesPath, 'utf-8'));
|
|
117
|
+
const goldenQueries = goldenQueriesData;
|
|
118
|
+
|
|
119
|
+
if (!Array.isArray(goldenQueries)) {
|
|
120
|
+
if (config.verbose) {
|
|
121
|
+
console.log('[Warning] Golden queries data is not an array');
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (config.verbose) {
|
|
127
|
+
console.log(`[Info] Loaded ${goldenQueries.length} golden queries for few-shot learning`);
|
|
128
|
+
}
|
|
129
|
+
return goldenQueries;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (config.verbose) {
|
|
132
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
133
|
+
console.log(`[Warning] Failed to load golden queries: ${message}`);
|
|
134
|
+
}
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
test('should successfully load golden queries with verbose=false', async () => {
|
|
140
|
+
const result = await loadGoldenQueries({ verbose: false });
|
|
141
|
+
|
|
142
|
+
assert.strictEqual(Array.isArray(result), true, 'Expected result to be an array');
|
|
143
|
+
assert.ok(result.length > 0, 'Expected result to have items');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('should return empty array when file does not exist', async () => {
|
|
147
|
+
// Create a version that uses a bad path
|
|
148
|
+
async function loadGoldenQueriesWithBadPath(config) {
|
|
149
|
+
try {
|
|
150
|
+
const badPath = '/nonexistent/path/golden-queries.json';
|
|
151
|
+
const goldenQueriesData = JSON.parse(readFileSync(badPath, 'utf-8'));
|
|
152
|
+
return goldenQueriesData;
|
|
153
|
+
} catch {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const result = await loadGoldenQueriesWithBadPath({ verbose: false });
|
|
159
|
+
|
|
160
|
+
assert.strictEqual(Array.isArray(result), true, 'Expected result to be an array');
|
|
161
|
+
assert.strictEqual(result.length, 0, 'Expected result to be empty');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('should return empty array when JSON is invalid', async () => {
|
|
165
|
+
// Create a version that parses invalid JSON
|
|
166
|
+
async function loadGoldenQueriesWithInvalidJson(config) {
|
|
167
|
+
try {
|
|
168
|
+
JSON.parse('{ invalid json }');
|
|
169
|
+
return [];
|
|
170
|
+
} catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const result = await loadGoldenQueriesWithInvalidJson({ verbose: false });
|
|
176
|
+
|
|
177
|
+
assert.strictEqual(Array.isArray(result), true, 'Expected result to be an array');
|
|
178
|
+
assert.strictEqual(result.length, 0, 'Expected result to be empty');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|