forked from extern/bruno
feat: generic key val line parser
This commit is contained in:
parent
b88848f0dc
commit
d9ef1692fe
@ -1,16 +1,9 @@
|
||||
const {
|
||||
between,
|
||||
regex,
|
||||
everyCharUntil,
|
||||
digit,
|
||||
whitespace,
|
||||
optionalWhitespace,
|
||||
endOfInput,
|
||||
choice,
|
||||
many,
|
||||
sepBy,
|
||||
sequenceOf
|
||||
everyCharUntil
|
||||
} = require("arcsecond");
|
||||
const keyvalLines = require('./key-val-lines');
|
||||
|
||||
// body(type=json)
|
||||
const bodyJsonBegin = regex(/^body\s*\(\s*type\s*=\s*json\s*\)\s*\r?\n/);
|
||||
@ -60,32 +53,6 @@ const bodyXmlTag = between(bodyXmlBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((
|
||||
}
|
||||
});
|
||||
|
||||
// generic key value parser
|
||||
const newline = regex(/^\r?\n/);
|
||||
const newLineOrEndOfInput = choice([newline, endOfInput]);
|
||||
const wordWithoutWhitespace = regex(/^[^\s\t\r?\n]+/g);
|
||||
const wordWithWhitespace = regex(/^[^\r?\n]+/g);
|
||||
|
||||
const line = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
whitespace,
|
||||
wordWithWhitespace,
|
||||
newLineOrEndOfInput
|
||||
]).map(([_, enabled, __, key, ___, value]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key,
|
||||
"value": value
|
||||
};
|
||||
});
|
||||
|
||||
const lines = many(line);
|
||||
const keyvalLines = sepBy(newline)(lines);
|
||||
|
||||
|
||||
/**
|
||||
* We have deprecated form-url-encoded type in body tag, it was a misspelling on my part
|
||||
* The new type is form-urlencoded
|
||||
|
@ -1,44 +1,18 @@
|
||||
const {
|
||||
sequenceOf,
|
||||
whitespace,
|
||||
optionalWhitespace,
|
||||
choice,
|
||||
endOfInput,
|
||||
between,
|
||||
digit,
|
||||
many,
|
||||
regex,
|
||||
sepBy
|
||||
} = require("arcsecond");
|
||||
|
||||
const newline = regex(/^\r?\n/);
|
||||
const newLineOrEndOfInput = choice([newline, endOfInput]);
|
||||
const { each } = require('lodash');
|
||||
const keyValLines = require('./key-val-lines');
|
||||
|
||||
const begin = regex(/^vars\s*\r?\n/);
|
||||
const end = regex(/^[\r?\n]*\/vars\s*[\r?\n]*/);
|
||||
const wordWithoutWhitespace = regex(/^[^\s\r?\t\n]+/g);
|
||||
const wordWithWhitespace = regex(/^[^\r?\n]+/g);
|
||||
|
||||
const line = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
whitespace,
|
||||
wordWithWhitespace,
|
||||
newLineOrEndOfInput
|
||||
]).map(([_, enabled, __, key, ___, value]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key,
|
||||
"value": value,
|
||||
"type": "text"
|
||||
};
|
||||
});
|
||||
const envVarsTag = between(begin)(end)(keyValLines).map(([variables]) => {
|
||||
each(variables, (variable) => {
|
||||
variable.type = "text"
|
||||
});
|
||||
|
||||
const lines = many(line);
|
||||
const envVarsLines = sepBy(newline)(lines);
|
||||
const envVarsTag = between(begin)(end)(envVarsLines).map(([variables]) => {
|
||||
return {
|
||||
variables
|
||||
};
|
||||
|
@ -1,43 +1,13 @@
|
||||
const {
|
||||
sequenceOf,
|
||||
whitespace,
|
||||
optionalWhitespace,
|
||||
choice,
|
||||
endOfInput,
|
||||
between,
|
||||
digit,
|
||||
many,
|
||||
regex,
|
||||
sepBy
|
||||
regex
|
||||
} = require("arcsecond");
|
||||
|
||||
const newline = regex(/^\r?\n/);
|
||||
const newLineOrEndOfInput = choice([newline, endOfInput]);
|
||||
const keyValLines = require('./key-val-lines');
|
||||
|
||||
const begin = regex(/^headers\s*\r?\n/);
|
||||
const end = regex(/^[\r?\n]*\/headers\s*[\r?\n]*/);
|
||||
const wordWithoutWhitespace = regex(/^[^\s\t\n]+/g);
|
||||
const wordWithWhitespace = regex(/^[^\r?\n]+/g);
|
||||
|
||||
const line = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
whitespace,
|
||||
wordWithWhitespace,
|
||||
newLineOrEndOfInput
|
||||
]).map(([_, enabled, __, key, ___, value]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key,
|
||||
"value": value
|
||||
};
|
||||
});
|
||||
|
||||
const lines = many(line);
|
||||
const headersLines = sepBy(newline)(lines);
|
||||
const headersTag = between(begin)(end)(headersLines).map(([headers]) => {
|
||||
const headersTag = between(begin)(end)(keyValLines).map(([headers]) => {
|
||||
return {
|
||||
headers
|
||||
};
|
||||
|
64
packages/bruno-lang/src/key-val-lines.js
Normal file
64
packages/bruno-lang/src/key-val-lines.js
Normal file
@ -0,0 +1,64 @@
|
||||
const {
|
||||
sequenceOf,
|
||||
whitespace,
|
||||
optionalWhitespace,
|
||||
choice,
|
||||
digit,
|
||||
many,
|
||||
regex,
|
||||
sepBy,
|
||||
} = require("arcsecond");
|
||||
|
||||
const newline = regex(/^\r?\n/);
|
||||
const wordWithoutWhitespace = regex(/^[^\s\r?\t\n]+/g);
|
||||
const wordWithWhitespace = regex(/^[^\r?\n]+/g);
|
||||
|
||||
// matching lines like: 1 key value
|
||||
const line = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
whitespace,
|
||||
wordWithWhitespace
|
||||
]).map(([_, enabled, __, key, ___, value]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key ? key.trim() : "",
|
||||
"value": value ? value.trim() : ""
|
||||
};
|
||||
});
|
||||
|
||||
// matching lines like: 1 key follows by [whitespaces] and a newline
|
||||
const line2 = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
regex(/^\s*\r?\n/)
|
||||
]).map(([_, enabled, __, key]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key,
|
||||
"value": ""
|
||||
};
|
||||
});
|
||||
|
||||
// matching lines like: 1 followed by [whitespaces] and a newline
|
||||
const line3 = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
regex(/^\s*\r?\n/)
|
||||
]).map(([_, enabled]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": "",
|
||||
"value": ""
|
||||
};
|
||||
});
|
||||
|
||||
const lines = many(choice([line3, line2, line]));
|
||||
|
||||
const keyValLines = sepBy(newline)(lines);
|
||||
|
||||
module.exports = keyValLines;
|
@ -1,44 +1,13 @@
|
||||
const {
|
||||
sequenceOf,
|
||||
whitespace,
|
||||
optionalWhitespace,
|
||||
choice,
|
||||
endOfInput,
|
||||
everyCharUntil,
|
||||
between,
|
||||
digit,
|
||||
many,
|
||||
regex,
|
||||
sepBy
|
||||
regex
|
||||
} = require("arcsecond");
|
||||
|
||||
const newline = regex(/^\r?\n/);
|
||||
const newLineOrEndOfInput = choice([newline, endOfInput]);
|
||||
const keyValLines = require('./key-val-lines');
|
||||
|
||||
const begin = regex(/^params\s*\r?\n/);
|
||||
const end = regex(/^[\r?\n]*\/params\s*[\r?\n]*/);
|
||||
const wordWithoutWhitespace = regex(/^[^\s\t\r?\n]+/g);
|
||||
const wordWithWhitespace = regex(/^[^\r?\n]+/g);
|
||||
|
||||
const line = sequenceOf([
|
||||
optionalWhitespace,
|
||||
digit,
|
||||
whitespace,
|
||||
wordWithoutWhitespace,
|
||||
whitespace,
|
||||
wordWithWhitespace,
|
||||
newLineOrEndOfInput
|
||||
]).map(([_, enabled, __, key, ___, value]) => {
|
||||
return {
|
||||
"enabled": Number(enabled) ? true : false,
|
||||
"name": key,
|
||||
"value": value
|
||||
};
|
||||
});
|
||||
|
||||
const lines = many(line);
|
||||
const paramsLines = sepBy(newline)(lines);
|
||||
const paramsTag = between(begin)(end)(paramsLines).map(([params]) => {
|
||||
const paramsTag = between(begin)(end)(keyValLines).map(([params]) => {
|
||||
return {
|
||||
params
|
||||
};
|
||||
|
230
packages/bruno-lang/tests/key-val-lines.spec.js
Normal file
230
packages/bruno-lang/tests/key-val-lines.spec.js
Normal file
@ -0,0 +1,230 @@
|
||||
const {
|
||||
between,
|
||||
regex,
|
||||
anyChar,
|
||||
many,
|
||||
choice
|
||||
} = require("arcsecond");
|
||||
const _ = require('lodash');
|
||||
|
||||
const keyValLines = require('../src/key-val-lines');
|
||||
|
||||
const begin = regex(/^vars\s*\r?\n/);
|
||||
const end = regex(/^[\r?\n]*\/vars\s*[\r?\n]*/);
|
||||
|
||||
const varsTag = between(begin)(end)(keyValLines).map(([variables]) => {
|
||||
return {
|
||||
variables
|
||||
};
|
||||
});
|
||||
|
||||
const toJson = (fileContents) => {
|
||||
const parser = many(choice([
|
||||
varsTag,
|
||||
anyChar
|
||||
]));
|
||||
|
||||
const parsed = parser
|
||||
.run(fileContents)
|
||||
.result
|
||||
.reduce((acc, item) => _.merge(acc, item), {});
|
||||
|
||||
const json = {
|
||||
variables: parsed.variables || []
|
||||
};
|
||||
|
||||
return json;
|
||||
};
|
||||
|
||||
describe('bool-key-val', () => {
|
||||
it('should parse bool-key-val - case 1', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host https://www.google.com
|
||||
/vars
|
||||
`;
|
||||
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: 'https://www.google.com'
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse bool-key-val - case 2', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host https://www.google.com
|
||||
1 auth jwt secret
|
||||
/vars
|
||||
`;
|
||||
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: 'https://www.google.com'
|
||||
}, {
|
||||
enabled: true,
|
||||
name: 'auth',
|
||||
value: 'jwt secret'
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// following test cases are for edge cases
|
||||
|
||||
// one line with just enabled flag
|
||||
it('should parse bool-key-val - case 3', () => {
|
||||
const file = `
|
||||
vars
|
||||
1
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: '',
|
||||
value: ''
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// one line with just enabled flag and a space
|
||||
it('should parse bool-key-val - case 4', () => {
|
||||
const file = `
|
||||
vars
|
||||
1
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: '',
|
||||
value: ''
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// one line with just enabled flag and a space and a name
|
||||
it('should parse bool-key-val - case 5', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: ''
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// one line with just enabled flag and a space and a name and a space
|
||||
it('should parse bool-key-val - case 6', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: ''
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// three lines, second line with just enabled flag
|
||||
it('should parse bool-key-val - case 7', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host https://www.google.com
|
||||
1
|
||||
0 Content-type application/json
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: 'https://www.google.com'
|
||||
}, {
|
||||
enabled: true,
|
||||
name: '',
|
||||
value: ''
|
||||
}, {
|
||||
enabled: false,
|
||||
name: 'Content-type',
|
||||
value: 'application/json'
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// three lines, second line with just enabled flag and a space
|
||||
it('should parse bool-key-val - case 8', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host https://www.google.com
|
||||
1
|
||||
0 Content-type application/json
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: 'https://www.google.com'
|
||||
}, {
|
||||
enabled: true,
|
||||
name: '',
|
||||
value: ''
|
||||
}, {
|
||||
enabled: false,
|
||||
name: 'Content-type',
|
||||
value: 'application/json'
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// three lines, second line with just enabled flag and a space and a name
|
||||
it('should parse bool-key-val - case 9', () => {
|
||||
const file = `
|
||||
vars
|
||||
1 host https://www.google.com
|
||||
1 auth
|
||||
0 Content-type application/json
|
||||
/vars
|
||||
`;
|
||||
const result = toJson(file);
|
||||
expect(result).toEqual({
|
||||
variables: [{
|
||||
enabled: true,
|
||||
name: 'host',
|
||||
value: 'https://www.google.com'
|
||||
}, {
|
||||
enabled: true,
|
||||
name: 'auth',
|
||||
value: ''
|
||||
}, {
|
||||
enabled: false,
|
||||
name: 'Content-type',
|
||||
value: 'application/json'
|
||||
}]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user