Skip to content

Commit 0d1fa12

Browse files
authored
fix: fix parse url issue (#222)
fix: fix parse url issue Refs: #221
1 parent ceb91db commit 0d1fa12

File tree

4 files changed

+131
-2
lines changed

4 files changed

+131
-2
lines changed

jest.config.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ module.exports = {
22
preset: 'ts-jest',
33
testEnvironment: 'node',
44
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
5+
moduleNameMapper: {
6+
'^monaco-editor$': '<rootDir>/node_modules/monaco-editor/esm/vs/editor/editor.api.js',
7+
},
58
};

src/common/monaco/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { executeActions, search } from './lexerRules.ts';
44
import { monacoEnvironment } from './environment.ts';
55
import { searchCompletionProvider } from './completion.ts';
66

7-
self.MonacoEnvironment = monacoEnvironment;
7+
// Only assign MonacoEnvironment if 'self' is defined (browser or web worker)
8+
if (typeof self !== 'undefined') {
9+
self.MonacoEnvironment = monacoEnvironment;
10+
}
811

912
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
1013
monaco.languages.register({ id: search.id });

src/common/monaco/tokenlizer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ const replaceTripleQuotes = (value: string) =>
134134
value
135135
.replace(/'''(.*?)'''/gs, (_, match) => jsonify.stringify(match))
136136
.replace(/"""(.*?)"""/gs, (_, match) => jsonify.stringify(match));
137-
const replaceComments = (value: string) => value.replace(/\/\/.*/g, '').trim();
137+
const replaceComments = (value: string) =>
138+
value.replace(/((['"]).*?\2)|\/\/.*$/gm, (match, quoted) => (quoted ? match : '')).trim();
138139

139140
export const transformQDSL = ({ path, qdsl }: Pick<SearchAction, 'path' | 'qdsl'>) => {
140141
try {
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { transformQDSL } from '../../../src/common/monaco';
2+
3+
jest.mock('monaco-editor', () => ({
4+
self: { MonacoEnvironment: {} },
5+
editor: {
6+
IModel: {},
7+
ITextModel: {},
8+
getLineCount: () => 1,
9+
getLineContent: () => '',
10+
},
11+
Range: {},
12+
Position: {},
13+
languages: {
14+
typescript: {
15+
typescriptDefaults: {
16+
setEagerModelSync: jest.fn(),
17+
},
18+
},
19+
register: jest.fn(),
20+
setMonarchTokensProvider: jest.fn(),
21+
setLanguageConfiguration: jest.fn(),
22+
registerCompletionItemProvider: jest.fn(),
23+
CodeLens: {},
24+
},
25+
}));
26+
27+
describe('Unit test for transformQDSL', () => {
28+
it('should transform QDSL string to JSON when given qdsl is valid', () => {
29+
const input = {
30+
path: '/test',
31+
qdsl: '{ "query": { "match_all": {} } }',
32+
};
33+
const result = transformQDSL(input);
34+
expect(result).toBe(JSON.stringify(JSON.parse(input.qdsl), null, 2));
35+
});
36+
37+
it('should handle _bulk path with multiple lines when a valid bulk qdsl provided', () => {
38+
const input = {
39+
path: '/_bulk',
40+
qdsl: '{ "index": {} }\n{ "field": "value" }',
41+
};
42+
const result = transformQDSL(input);
43+
const expected =
44+
JSON.stringify(JSON.parse('{ "index": {} }')) +
45+
'\n' +
46+
JSON.stringify(JSON.parse('{ "field": "value" }')) +
47+
'\n';
48+
expect(result).toBe(expected);
49+
});
50+
51+
it('should remove comments and triple quotes', () => {
52+
const input = {
53+
path: '/test',
54+
qdsl: '{ "query": { "match_all": {} } } // comment',
55+
};
56+
const result = transformQDSL(input);
57+
expect(result).toBe(JSON.stringify({ query: { match_all: {} } }, null, 2));
58+
});
59+
60+
it('should throw CustomError on invalid JSON', () => {
61+
const input = {
62+
path: '/test',
63+
qdsl: '{ invalid json }',
64+
};
65+
expect(() => transformQDSL(input)).toThrow();
66+
});
67+
68+
it('should not remove // inside qoutes', () => {
69+
const input = {
70+
path: '/test',
71+
qdsl: '{ "query": { "match": { "field": "http://example.com//foo" } } } // comment',
72+
};
73+
const result = transformQDSL(input);
74+
// The comment should be removed, but the // inside the string should remain
75+
expect(result).toBe(
76+
JSON.stringify(
77+
{
78+
query: {
79+
match: {
80+
field: 'http://example.com//foo',
81+
},
82+
},
83+
},
84+
null,
85+
2,
86+
),
87+
);
88+
});
89+
90+
it('should handle URLs with // inside JSON and not treat them as comments', () => {
91+
const input = {
92+
path: '/detail/_search',
93+
qdsl: `{
94+
"from": 0,
95+
"size": 10,
96+
"query": {
97+
"bool": {
98+
"must": [
99+
{
100+
"terms": {
101+
"url": ["https://baidu.com/"]
102+
}
103+
}
104+
]
105+
}
106+
}
107+
}`,
108+
};
109+
const result = transformQDSL(input);
110+
expect(result).toBe(
111+
JSON.stringify(
112+
{
113+
from: 0,
114+
size: 10,
115+
query: { bool: { must: [{ terms: { url: ['https://baidu.com/'] } }] } },
116+
},
117+
null,
118+
2,
119+
),
120+
);
121+
});
122+
});

0 commit comments

Comments
 (0)